I am trying to create a visual grid of this http://www.ibm.com/developerworks/library/j-coordconvert/ -Military Grid Reference System. I have the latitude/longitude to UTM and also to MGRS...which ar
17 T 330649 4689666
17TLG3064989666
But when going from MGRS to latitude I get the following:
[D#18e3f02a
public class CoordinateConversion {
public static void main(String args[]) {
CoordinateConversion test = new CoordinateConversion();
CoordinateConversion test2 = new CoordinateConversion();
test.latLon2UTM(35.58, 82.56);
System.out.println(test.latLon2UTM(42.340837, -83.055821));
System.out.println();
test2.latLon2UTM(35.58, 82.56);
System.out.println(test2.latLon2MGRUTM(42.340837, -83.055821));
CoordinateConversion test3 = new CoordinateConversion();
test3.latLon2UTM(35.58, 82.56);
//System.out.print(test3.mgrutm2LatLong(42.340837, -83.055821));
//System.out.println(test3.mgrutm2LatLong("02CNR0634657742"));
MGRUTM2LatLon mg = new MGRUTM2LatLon();
//mg.convertMGRUTMToLatLong("02CNR0634657742");
String MGRUTM = "17TLG3064989666";
System.out.println(mg.convertMGRUTMToLatLong(MGRUTM));
//for loop to be developed
}
public double[] utm2LatLon(String UTM) {
UTM2LatLon c = new UTM2LatLon();
return c.convertUTMToLatLong(UTM);
}
public double[] mgrutm2LatLon(String MGRUTM) {
MGRUTM2LatLon c = new MGRUTM2LatLon();
return c.convertMGRUTMToLatLong(MGRUTM);
}
}
and from this class:
public double[] convertMGRUTMToLatLong(String mgrutm) {
double[] latlon = {0.0, 0.0};
// 02CNR0634657742
int zone = Integer.parseInt(mgrutm.substring(0, 2));
String latZone = mgrutm.substring(2, 3);
String digraph1 = mgrutm.substring(3, 4);
String digraph2 = mgrutm.substring(4, 5);
easting = Double.parseDouble(mgrutm.substring(5, 10));
northing = Double.parseDouble(mgrutm.substring(10, 15));
LatZones lz = new LatZones();
double latZoneDegree = lz.getLatZoneDegree(latZone);
double a1 = latZoneDegree * 40000000 / 360.0;
double a2 = 2000000 * Math.floor(a1 / 2000000.0);
Digraphs digraphs = new Digraphs();
double digraph2Index = digraphs.getDigraph2Index(digraph2);
double startindexEquator = 1;
if ((1 + zone % 2) == 1) {
startindexEquator = 6;
}
double a3 = a2 + (digraph2Index - startindexEquator) * 100000;
if (a3 <= 0) {
a3 = 10000000 + a3;
}
northing = a3 + northing;
zoneCM = -183 + 6 * zone;
double digraph1Index = digraphs.getDigraph1Index(digraph1);
int a5 = 1 + zone % 3;
double[] a6 = {16, 0, 8};
double a7 = 100000 * (digraph1Index - a6[a5 - 1]);
easting = easting + a7;
setVariables();
double latitude = 0;
latitude = 180 * (phi1 - fact1 * (fact2 + fact3 + fact4)) / Math.PI;
if (latZoneDegree < 0) {
latitude = 90 - latitude;
}
double d = _a2 * 180 / Math.PI;
double longitude = zoneCM - d;
if (getHemisphere(latZone).equals("S")) {
latitude = -latitude;
}
latlon[0] = latitude;
latlon[1] = longitude;
return latlon;
}
I am trying not to get into a large library where I will have to learn things that may be time consuming.
So I am trying to loop so I go east (easting) and north (northing) and cannot get past the point where I have one point - latitude/longitude.
Hope I have asked my question clearly without stating too much.
Any help will be appreciated.
Thanks,
-Terry
Your result from convertMGRUTMToLatLong() is an array of doubles, and by default, arrays are converted to String in a rather unreadable format in Java. That's where the [D#18e3f02a comes from. Try System.out.println(Arrays.toString(mg.convertMGRUTMToLatLong(MGRUTM))); and you'll get a more readable output.
In the method convertMGRUTMToLatLong(String s) you are returning an array latlon (i.e an object).
It returns its hashcode which is probably u dont want.
You want to print the array values. So in your main method you replace below line;
System.out.println(mg.convertMGRUTMToLatLong(MGRUTM));
with
double[] a = mg.convertMGRUTMToLatLong(MGRUTM) ;
System.out.println(a[0]+" " + a[1] );
Hope that helps!
Related
I've had a lot of experience with Java, and have already written my own utilities for processing imagery. I realise that there are many tutorials out there for Python, but I'm much more inclined to use Java as I would like to integrate some of the facilities of OpenCV 4.1 with my existing Java code.
One of my experiments is to try and obtain the masks of objects identified ion images using the coco dataset
// Give the textGraph and weight files for the model
private static final String TEXT_GRAPH = "models/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt";
private static final String MODEL_WEIGHTS = "models/mask_rcnn_inception_v2_coco_2018_01_28/frozen_inference_graph.pb";
private static final String CLASSES_FILE = "models/mscoco_labels.names";
TextFileConsumer consumer = new TextFileConsumer();
File textFile = new File(CLASSES_FILE);
if (textFile.exists()){
BufferedReader fr1 = new BufferedReader(new FileReader(textFile));
fr1.lines().forEach(consumer::storeLines);
}
String[] CLASSES = consumer.lines.toArray(new String[0]);
Mat image = Imgcodecs.imread("images/bird.jpg");
Size size = image.size();
int cols = image.cols();
int rows = image.rows();
double h = size.height;
double w = size.width;
int hh = (int)size.height;
int ww = (int)size.width;
Mat blob = org.opencv.dnn.Dnn.blobFromImage(image, 1.0, new Size(w, h), Scalar.all(0), true, false);
// Load the network
Net net = org.opencv.dnn.Dnn.readNetFromTensorflow(MODEL_WEIGHTS, TEXT_GRAPH);
net.setPreferableBackend(org.opencv.dnn.Dnn.DNN_BACKEND_OPENCV);
net.setPreferableTarget(org.opencv.dnn.Dnn.DNN_TARGET_CPU);
net.setInput(blob);
ArrayList<String> outputlayers = new ArrayList<String>();
ArrayList<Mat> outputMats = new ArrayList<Mat>();
outputlayers.add("detection_out_final");
outputlayers.add("detection_masks");
net.forward(outputMats,outputlayers);
Mat numClasses = outputMats.get(0);
numClasses = numClasses.reshape(1, (int)numClasses.total() / 7);
for (int i = 0; i < numClasses.rows(); ++i) {
double confidence = numClasses.get(i, 2)[0];
//System.out.println(confidence);
if (confidence > 0.2) {
int classId = (int) numClasses.get(i, 1)[0];
String label = CLASSES[classId] + ": " + confidence;
System.out.println(label);
int left = (int)(numClasses.get(i, 3)[0] * cols);
int top = (int)(numClasses.get(i, 4)[0] * rows);
int right = (int)(numClasses.get(i, 5)[0] * cols);
int bottom = (int)(numClasses.get(i, 6)[0] * rows);
System.out.println(left + " " + top + " " + right + " " + bottom);
}
}
Mat numMasks = outputMats.get(1);
So far so good. My problem now is trying to obtain the segmentation shapes from numMasks Mat.
The size gives 90x100, total 2025000 and type -1*-1*CV_32FC1, isCont=true, isSubmat=true.
I know I have to reshape too, perhaps like this:
numMasks = numMasks.reshape(1, (int)numMasks.total() / 90);
Any help would be greatly appreciated.
Further edit
I think the masks are 15 x 15.
90 x 100 x 15 x 15 gives 2025000 so that gives me the total I saw earlier so I need to resize a mask and mix with original image.
I have two geo points that create a box (each point is a corner). I want to create a slightly bigger box. The following snippet is the code that creates the box.
private Box createRouteBox(DirectionsRoute route){
Box box;
Bounds bounds = route.bounds;
LatLng northeast = bounds.northeast;
LatLng southwest = bounds.southwest;
Point northeastPoint = new Point(northeast.lng, northeast.lat);
Point southwestPoint = new Point(southwest.lng, southwest.lat);
box = new Box(northeastPoint, southwestPoint);
return box;
}
Could you give me a suggestion how to move forward?
try something like this
private Box expandedBox(Point northeastPoint, Point southwestPoint){
// percentage of distance to set as padding to the box
Double offset = 0.1;
Double distance = pointDistance(northeastPoint, southwestPoint);
Double padding = (distance * offset);
// get current x, y
Double neX = northeastPoint.getX();
Double neY = northeastPoint.getY();
Double swX = southwestPoint.getX();
Double swY = southwestPoint.getY();
// init new x, y
Double neX2, neY2, swX2, swY2;
if(neX > swX){
neX2 = neX + padding;
swX2 = swX - padding;
} else {
neX2 = neX - padding;
swX2 = swX + padding;
}
if(neY > swY){
neY2 = neY + padding;
swY2 = swY - padding;
} else {
neY2 = neY - padding;
swY2 = swY + padding;
}
northeastPoint = new Point(neX2, neY2);
southwestPoint = new Point(swX2, swY2);
return new Box(northeastPoint, southwestPoint);
}
private Double pointDistance(Point p1, Point p2) {
return Math.sqrt((p2.getY() - p1.getY()) * (p2.getY() - p1.getY()) + (p2.getX() - p1.getX()) * (p2.getX() - p1.getX()));
}
You can change the offset to a percentage of the distance you want.
I'm currently trying to add some JUnit tests to my pathdrawing system in order to check if the calculations are right...
Currently I have:
Class to Test(MapRouteDrawer.java):
protected static double[] getCoords(PolynomialSplineFunction curve, double[] index) {
final double detailLevel = 1.0;//Tweak this value in order to achieve good rendering results
final double defaultCoordSize = index[index.length - 1];
final double[] coords = new double[(int)Math.round(detailLevel * defaultCoordSize) + 1];
final double stepSize = curve.getKnots()[curve.getKnots().length - 1] / coords.length;
double curValue = 0;
for (int i = 0; i < coords.length; i ++) {
coords[i] = curve.value(curValue);//gets y value of specified x value
curValue += stepSize;
}
return coords;
}
protected static double[] getIndex(Point[] points) {
final double[] index = new double[points.length];
if(index.length > 0){
index[0] = 0;
}
for (int i = 1; i < points.length; i++) {
index[i] = index[i - 1] + Math.sqrt(points[i - 1].distance(points[i]));
}
return index;
}
TestClass:
private Point[] dummyPoints = new Point[]{new Point(0,0), new Point(100,0), new Point(0,100)};//Some Points for Testing
//This returns a so called index - the squareroot distance between addedn on top of each other
private double[] dummyIndex = MapRouteDrawer.getIndex(dummyPoints);
#Test
public void testCurve(){
final double[] testYValues = new double[]{20, 40, 90};
final PolynomialSplineFunction testFunction = new SplineInterpolator().interpolate(dummyIndex, testYValues);//get a Spline-Interpolated curve
final double[] coords = MapRouteDrawer.getCoords(testFunction, dummyIndex);//Calls the function to test
final double factor = testFunction.getKnots()[testFunction.getKnots().length - 1] / coords.length;
assertEquals(testYValues[0] * factor, coords[(int)Math.round(dummyIndex[0])], 1);//Check if the coordinates are equal
assertEquals(testYValues[1] * factor, coords[(int)Math.round(dummyIndex[1])], 1);
assertEquals(testYValues[2] * factor, coords[(int)Math.round(dummyIndex[2])], 1);
}
This is working fine, but if you are familiar with JUnit you may notice the delta of 1 which is neccesary in order for this Test to work...
What I'm trying to achieve is this:
#Test
public void testCurve(){
final double[] testYValues = new double[]{20, 40, 90};
final PolynomialSplineFunction testFunction = new SplineInterpolator().interpolate(dummyIndex, testYValues);//get a Spline-Interpolated curve
final double[] coords = MapRouteDrawer.getCoords(testFunction, dummyIndex);//Calls the function to test
final double factor;//Unknown... should be dynamic, so it does not matter which detail level I chose
assertEquals(testYValues[0], coords[(int)Math.round(dummyIndex[0])] * factor, 0);//Check if the coordinates are equal
assertEquals(testYValues[1], coords[(int)Math.round(dummyIndex[1])] * factor, 0);//e.g. coords[(int)Math.round(dummyIndex[0])] * factor == 20 etc.
assertEquals(testYValues[2], coords[(int)Math.round(dummyIndex[2])] * factor, 0);
}
So that the first value in assertEquals() is 20, 40, 90 etc. and not a weird 21.39587576787686 (or similar) number and the delta is 0 (or 0.01 if there is no other way) and not 1 which I'm currently using
Because I'm using a detail level in my getCoords() method, which should be able to be adjusted without having to change the test, there is a need to make the "factor" in my test related to the coords-size.
How would I calculate the factor in order for the Test to succeed?
Any help is would be very much appreciated
I am writing ESRI geometry compression algorithm in JAVA, I am using this link.
Using instructions mentioned in provided link, this is my current code:
public static void main(String[] args) {
String dirPoints = "-118.356654545455,34.1146;-118.356436363636,34.1143272727273;-118.356418181818,34.1142363636364;-118.356490909091,34.1137636363636";
String compressedGeometry = "";
double xPointPrev = 0.0;
double yPointPrev = 0.0;
int coefficient = 55000;
String coefficient_32 = Integer.toString(coefficient, 32);
compressedGeometry = coefficient_32 + compressedGeometry;
String[] path_XY = dirPoints.split(";");
for (int i = 0, leni = path_XY.length; i < leni; i++) {
String[] xy = path_XY[i].split(",");
double pointX = Double.parseDouble(xy[0].trim());
double pointY = Double.parseDouble(xy[1].trim());
int xDifference = (int) Math.round(coefficient * (pointX - xPointPrev));
int yDifference = (int) Math.round(coefficient * (pointY - yPointPrev));
String xDifference_32 = Integer.toString(xDifference, 32);
compressedGeometry += xDifference_32;
String yDifference_32 = Integer.toString(yDifference, 32);
compressedGeometry += yDifference_32;
xPointPrev = pointX;
yPointPrev = pointY;
}
System.out.println(compressedGeometry);
}
Expected output: "+1lmo-66l1f+1p8af+c-f+1-5-4-q"
But I am getting this: "1lmo-66l1g1p8afc-f1-5-4-q"
What am I missing? Any help is highly appreciated.
Thanks,
According to Integer.toString()
"If the first argument is not negative, no sign character appears in the result."
Therefore I think you need to add the "+".
(And I think the f-g there is their typo).
Hey guys i have problem making percentege of double number.
double pom = cumulativeProbability(GetZ(baby));
Log.d("Pom","" + pom);
double pom1 = round(cumulativeProbability(GetZ(baby)),2);
Log.d("Pom1", "" + pom1);
double pom2 = pom1 * 100;
Log.d("Pom2: ", "" + pom2);
Here are logs:
06-05 02:30:04.574 13208-13208/com.bojan.readfromcsv D/Pom﹕ 0.5821510290598115
06-05 02:30:04.584 13208-13208/com.bojan.readfromcsv D/Pom1﹕ 0.58
06-05 02:30:04.584 13208-13208/com.bojan.readfromcsv D/Pom2:﹕ 57.99999999999999
I want to round this given pom value into two decimals and that i get with this round function:
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
For final result pom2 I want to have 58 %.... Tnx
Hopefully this will help:
public class t {
public static void main(String args[]) {
double pom = 0.5821510290598115;
System.out.println("pom = "+pom);
double pom1 = Math.round(pom*100)/100.0;
System.out.println("pom1 = "+pom1);
System.out.println("pom2 = "+Math.round(pom1*100));
}
}
Which produces:
$ java t
pom = 0.5821510290598115
pom1 = 0.58
pom2 = 58
If you want to preserve some more digits in pom2, say 2, do this:
System.out.println("pom2 = "+Math.round(pom1*100*100)/100.0);
Try:
double pom2 = round(pom1 * 100, 0);
EDIT:
int pom2 = (int) round(pom1 * 100, 0);
I assume you aren't having to write your own round function, so why not use:
pom2 = (int) Math.round(pom1 * 100);