How can I split a MultyPolygon in JTS into Polygons? - geotools

I am using JTS and I have one big Multypolygon with seperated Areas. How can I get a List of Polygons representing these seperated areas.
Thanks in Advance
Lukas

This is fairly simple, given a MultiPolygon p:
ArrayList<Polygon> polygons = new ArrayList<>();
for (int i = 0; i < p.getNumGeometries(); i++) {
Polygon polygon = (Polygon)p.getGeometryN(i);
polygons.add(polygon)
}

Related

Calculate large distance between two points using GeoTools

New to GeoTools and GIS and I am trying to calculate distance between Mumbai and Durban using GeoTools library. I am getting close to accurate results for small distances but when i go for bigger ones,the calculation is way too offcourse by 2000 km, i dont completely understand the CRS system .Below is my Code to calculate the distance between Mumbai and Durban
Coordinate source = new Coordinate(19.0760, 72.8777); ///Mumbai Lat Long
Coordinate destination1 = new Coordinate(-29.883333, 31.049999); //Durban Lat Long
GeometryFactory geometryFactory = new GeometryFactory();
Geometry point1 = geometryFactory.createPoint(source);
Geometry point2 = geometryFactory.createPoint(destination1);
CoordinateReferenceSystem auto = auto = CRS.decode("AUTO:42001,13.45,52.3");
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
Geometry g3 = JTS.transform(point1, transform);
Geometry g4 = JTS.transform(point2, transform);
double distance = g3.distance(g4);
This is what happens when you copy code blindly from stackexchange questions without reading the question it was based on which explains why.
All the times I've answered that question (and posted code like that) the questioner is trying to use lat/lon coordinates in degrees to measure a short distance in metres. The trick shown in your question creates an automatic UTM projection centred on the position specified after the "AUTO:42001," bit (in your case 52N 13E) - this needs to be the centre of the area you are interested in, so in your case those values are probably wrong anyway.
But you aren't interested in a small region Mumbai to Durban is a significant way around the Earth so you need to allow for the curvature of the Earth's surface. Also you aren't trying to do something difficult for which JTS is the only source of process (e.g buffering). In this case you should use the GeodeticCalculator which takes the shape of the Earth into account using the library from C. F. F. Karney, Algorithms for geodesics, J. Geodesy 87, 43–55 (2013).
Anyway enough explanation that no one will read in the future, here's the code:
public static void main(String[] args) {
DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84;
if (args.length != 4) {
System.err.println("Need 4 numbers lat_1 lon_1 lat_2 lon_2");
return;
}
GeometryFactory geomFactory = new GeometryFactory();
Point[] points = new Point[2];
for (int i = 0, k = 0; i < 2; i++, k += 2) {
double x = Double.valueOf(args[k]);
double y = Double.valueOf(args[k + 1]);
if (CRS.getAxisOrder(crs).equals(AxisOrder.NORTH_EAST)) {
System.out.println("working with a lat/lon crs");
points[i] = geomFactory.createPoint(new Coordinate(x, y));
} else {
System.out.println("working with a lon/lat crs");
points[i] = geomFactory.createPoint(new Coordinate(y, x));
}
}
double distance = 0.0;
GeodeticCalculator calc = new GeodeticCalculator(crs);
calc.setStartingGeographicPoint(points[0].getX(), points[0].getY());
calc.setDestinationGeographicPoint(points[1].getX(), points[1].getY());
distance = calc.getOrthodromicDistance();
double bearing = calc.getAzimuth();
Quantity<Length> dist = Quantities.getQuantity(distance, SI.METRE);
System.out.println(dist.to(MetricPrefix.KILO(SI.METRE)).getValue() + " Km");
System.out.println(dist.to(USCustomary.MILE).getValue() + " miles");
System.out.println("Bearing " + bearing + " degrees");
}
Giving:
working with a lon/lat crs
POINT (72.8777 19.076)
POINT (31.049999 -29.883333)
7032.866960793305 Km
4370.020928274692 miles
Bearing -139.53428618565218 degrees

LibGDX - given an arraylist of moving circles, how can i check for collision between them?

So I have 3 classes, MyGdxGame, Ball and DetectCollision. MyGdxGame initialises 4 instances of Ball (different colours and speed/direction, all bounce off the sides of the screen) and stores them as an arraylist.
This arraylist is passed through the constructor of DetectCollision:
public class DetectCollisions {
ArrayList<Ball> ball;
public DetectCollisions(ArrayList<Ball> ball) {
this.ball = ball;
start();
}
public void start() {
for(int i=0; i<ball.size();i++) {
...
}
}
Can anyone give me a hint as to where I should go with this? I just want to detect every time a ball collides with another (and eventually I'll have it print the number of collisions).
Any help highly appreciated :)
If you are going to add a lot of objects to the arraylist, use a 2D physics engine to do all the work for you. If you want to continue implementing your own functions, the very basic method to do is to implement a nested loop over the list to check every possible pair in the arraylist. The complexity is O(n^2)
for(int i=0; i<ball.size();i++) {
for(int j=i+1; j<ball.size();j++) {
check(ball.get(i), ball.get(j));
}
}
The method named check checks if given two circles collide or not. Checking two circles' collision is very easy. If the distance between the central points of the circles is smaller than the sum of the radiuses of the circles, then they collide. Check this page for further info about this.
This is very easy to accomplish if you let each Ball have bounds of type Circle.
You can make a circle as follows: Circle ballBounds = new Circle(float x, float y, float radius) This circle can act as the bounds of each ball ultimately allowing you to check if they collide using the Intersector class.
Having each Ball's boundary we can easily loop through the ArrayList<Ball> and check how many collide. For example:
ArrayList<Ball> ball = new ArrayList<Ball>(); // You need to add Balls to this ArrayList
Intersector intersector = new Intersector();
int counter = 0;
for(int i = 0; i < ball.size()-2; i++){
if(intersecor.overlaps(ball.get(i), ball.get(i+1)){
counter++;
}
i++;
}

Compute the distance between polyline (route) and marker in Google Maps API v3

Is there any convenient way to compute the direct (shortest) distance between Polyline (the route generated by Google Directions) and markers that are NOT situated on that polyline?
The only way I found out is to cycle through Polyline.getPath() vertices manually to calculate the shortest distance but it seems to be a bit harsh:
var path = routes[0].overview_path;
for (var i = 0; i < data.points.length; i++) {
var latLngA = new LatLng(data.points[i].lat, data.points[i].lng);
var shortest_distance = null;
for (var j = 0; j < path.length; j++) {
var distance = google.maps.geometry.spherical.computeDistanceBetween(latLngA, path[i]);
if (shortest_distance == null || distance < shortest_distance) {
shortest_distance = distance;
}
}
console.log(data.points[i].point_title, shortest_distance);
}
Thanks in advance!
As far as I know, the Google Maps API does not give you a way to do this easily. And unfortunately, the algorithm you use will not give an accurate answer, because it gives the distance from the marker to the closest vertex on the path, not the closest point on the polyline itself, which will usually not be one of the points.
If you really need an accurate calculation, the best option I know of is to use the Javascript Topology Suite (JSTS). JSTS has a ton of geographic formulas for calculating this sort of thing. That means converting the polyline returned from the directions API into a JSTS object and calling the right utility function. Not trivial, but not too difficult either.
Use turf - modular geospatial analysis engine.
https://turfjs.org/docs/

Google Map Bound Calculation without Javascript

Do anybody know how the google map bound calculation can be done without using any UI element and Javascript.
I have set of points and different zoom level. I can probably add the screen size and I need to calculate the bounds for provided coordinate and zoom level. I am trying to do this in the plain C# code.
Please help.
as for calculating bounds - you can do it easily by walking array of your coordinates and extend bounds rectangle if point falls out. First coord is a start. I don't familiar with C# but there is the algo using pseudocode:
points = Array of coord(lat, lng)
bounds = object {
top: null
left: null
right: null
bottom: null
function extend(coord: (lat, lng))
{
if (this.top == null) // empty
{
this.top = coord.lat; this.bottom = coord.lat;
this.left = coord.lng; this.right = coord.lng;
}
else
{
if (coord.lng < this.left) this.left = coord.lng;
if (coord.lat < this.bottom) this.bottom = coord.lat;
if (coord.lng > this.right) this.right = coord.lng;
if (coord.lat > this.top) this.top = coord.lat;
}
}
}
But of course much simplier way is to use already written google functionality.
Zoom level can be calculated somehow from the size of bounding box (for example you can find a table with rates in km or miles per pixel, or approximate width or map), but most comfortable way is map.fitBounds(bounds)

google maps : How to find if any markers inside map

I have divided the my google map display in to numbers of parts, Now I want of find it out if any markers are positioned inside a/any particulate cell.
Any Help ?
Farther Explained :
I have got the map bounds by
map.getBounds();
method and then farther divide it into numbers of sub-bounds.
also I have putted markers as
map.addOverlay(markerObject);
Now , I want find if of the cells (which I got by dividing the map by bounds) is containing any markers or not .
I have divide the entire map bounds into numbers of sub bounds
So keep all markers in array. Each marker has a method called get_position( ). After you have finished division of map bound into small sub bounds, you just need to iterate over the sub bounds and check whenever the marker within it.
PS. Also take a look on it, in some cases could be useful.
Suppose you on sub bound cell:
var sub_bounds = new Array();
// here you've pushed into an array the sub bounds
for ( var i = 0; i<sub_bounds.length; ++i)
{
for ( var j = 0; j < markers.length; ++j)
{
var lat = markers[j].get_position( ).lat;
var lng = markers[j].get_position( ).lng;
if ( sub_bounds[i].sw.lat<lat && lat<sub_bounds[i].ne.lat &&
sub_bounds[i].sw.lng<lng && lng<sub_bounds[i].ne.lng)
// marker within cell, do whatever you need to do
}
}
Here is an alternative to the above solution without re-iteration:
First - how big are your sub_bounds? Say 10 latitude and longitude degrees each.
Second - The position of the marker is (floor(marker.lat / 10), floor(marker.lng / 10))
Third - Each marker is added to the map and dropped in a bucket for that subdomain.
so (40, -78) would lie in bucket (4,7) i.e. bucket["4~7"]
Correction: would lie in bucket (4,-7) i.e. bucket["4~-7"]
which would contain all markers between 40 and 50 lat and -70 and -80 lng.
You can use GLatLngBounds as the object that holds all these markers in each bucket, which would give you a good set of methods to use, such as calculating center of the bucket depending on the markers currently in it.
Probably the best solution is given here: how to find out whether a point is inside a polygone:
How to detect that a point is inside a Polygon using Google Maps?