With monday.comâ€™s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.
Dim XDim As Integer, yDim As Integer, delX As Decimal, _
tlLon As Double, brLon As Double, delY As Decimal, _
tlLat As Double, brLat As Double
Dim myLattitude As Double, myLon As Double
XDim = 640
yDim = 425
tlLon = -1.136182
brLon = -1.133490
tlLat = 52.668572
brLat = 52.666803
delX = (tlLon - (brLon)) / XDim
txtLon.Text = delX
delY = (tlLat - brLat) / yDim
txtLat.Text = delY
Dim y As Integer = 95
myLattitude = tlLat - y * delY
Dim X As Integer = 58
myLon = tlLon - X * delX
txt1.Text = myLattitude
txt2.Text = myLon
public static void Test() {
Matrix imgToGeo = Transform(
new PointF(-1.136182f, 52.668572f),
new PointF(-1.13349f, 52.666803f),
new Point(0, 0),
new Point(88, 666)
);
Matrix geoToImg = imgToGeo.Clone();
geoToImg.Invert();
// Create a set of points inside the image
PointF[] pOrig = new PointF[] {
new PointF(0, 0),
new PointF(68, 79) ,
new PointF(88, 666)
};
// Transform the image points to geoditic
PointF[] pGeo = (PointF[])pOrig.Clone();
imgToGeo.TransformPoints(pGeo);
// Transform the geoditic points back to image points
PointF[] pImage = (PointF[])pGeo.Clone();
geoToImg.TransformPoints(pImage);
}
private static void Rhumb(PointF p1, PointF p2, out double distance, out double heading) {
// Average Radius of the earth in metres
double R = 6371000;
// Natively use radians
p1.X = (float)(p1.X * Math.PI / 180);
p1.Y = (float)(p1.Y * Math.PI / 180);
p2.X = (float)(p2.X * Math.PI / 180);
p2.Y = (float)(p2.Y * Math.PI / 180);
/* Phi = Latitude
* Lambda = Longitude
*/
double dPhi = (p2.Y - p1.Y);
double dLambda = (p2.X - p1.X);
double dX = dLambda;
double dY = Math.Log(
Math.Tan((Math.PI / 4) + ((double)p2.Y / 2))
/ Math.Tan((Math.PI / 4) + ((double)p1.Y / 2))
);
double q;
if (p1.Y == p2.Y) {
q = Math.Cos(p1.Y);
} else {
q = dPhi / dY;
}
// Distance between points in metres
distance = Math.Sqrt(
Math.Pow(dPhi, 2) + Math.Pow(q * dLambda, 2)
) * R;
// Heading from p1 -> p2 in degrees
heading = ((Math.Atan2(dX, dY) * 180 / Math.PI) + 360) % 360;
}
private static Matrix Transform(PointF geoTL, PointF geoBR, Point imgTL, Point imgBR ) {
/* Calculate the angle that image has been rotated
* Can use Rhumb bearing between 2 geoditic points as the scale
* is small.
* Using rhumb bearing will cause inacuracies over larger scales
*/
float rotate;
{
// Rhumb bearing
double d, thetaRhumb;
Rhumb(geoTL, geoBR, out d, out thetaRhumb);
// Angle from Top-left -> bottom-right on the image
double thetaImage = (Math.Atan2(imgBR.X - imgTL.X, imgBR.Y - imgTL.Y) * 180 / Math.PI);
rotate = (float)(180 - thetaImage - thetaRhumb);
}
/* Create Transformation matrix
* 1). Translate image point to origin
* 2). Rotate the the point about the origin
* Negative, as we're rotating back
*/
Matrix m = new Matrix();
m.Translate(-imgTL.X, -imgTL.Y);
m.Rotate(-rotate, MatrixOrder.Append);
/* Calcualate the scale
* 1). Get the transformed & rotated value for Point2
* 2). Use this new point to determine the X & Y axis scales
*/
float sX, sY;
{
PointF[] pTemp = new PointF[] { new PointF(imgBR.X, imgBR.Y) };
m.TransformPoints(pTemp);
sX = (float)((geoBR.X - geoTL.X) / pTemp[0].X);
sY = (float)((geoBR.Y - geoTL.Y) / pTemp[0].Y);
}
/* Final part of the transformation matrix
* 1). Set the X & Y scaling
* 2). Translate transformed point back to geoditic coordinate
*/
m.Scale(sX, sY, MatrixOrder.Append);
m.Translate(geoTL.X, geoTL.Y, MatrixOrder.Append);
return m;
}
Foo.jpg
xDim= 210
yDim = 806