How can I draw a polygon on intersection coordinates on Nutiteq? - eclipse

Hey people this is going to be my first question so dont hit me too hard !
Before I have already added polygons but the intersection is a bit complicating.
with pre-defined i mean for example intersection coordinates of two other polygons. I'm calculating the area of the polygon intersection but i also want to highlight the area. Thanks

You would need two steps:
calculate intersection: polygon from 2 polygons. I would use JTS for it, you would need to provide data in JTS objects.
highlight the intersection on mapview (nutiteq for example). You can just add the resulting polygon as one geometry element into geometry layer, just as any other polygon. Use special styling to make it look different. You would need to convert JTS polygon to Nutiteq Polygon object to show it on map

ArrayList<MapPos> keslist = new ArrayList<MapPos>();
for (int i = 0; i < sonuc.getNumPoints(); i++) {
double lon = sonuc.getX(i);
double lat = sonuc.getY(i);
MapPos mPos = new MapPos(lon, lat);
keslist.add(mPos);
}
PolygonStyle polygonStyle = PolygonStyle.builder().setColor(Color.GREEN).build();
StyleSet<PolygonStyle> polygonStyleSet = new StyleSet<PolygonStyle>(null);
polygonStyleSet.setZoomStyle(10, polygonStyle);
Polygon KesisimPol = new Polygon(keslist, new DefaultLabel("Kesişim"), polygonStyleSet, null);
GeometryLayer geomLayer = new GeometryLayer(mapView.getLayers().getBaseLayer().getProjection());
mapView.getLayers().addLayer(geomLayer);
geomLayer.add(KesisimPol);
}
Here is my solution. I've tried it works. Right now I'm trying to add this new polygon to editable objects layer. Because I can't use the result polygon in another intersection process.
I hope this will help the others.

Related

How to get the edge of a polygon drawn on map within Leaflet

I am working with Leaflet and Leaflet-Draw in Angular to draw some polygons on the Google Map. How can I implement a listener when the user clicks exactly on the edge of the drawn polygons and get the lat and lng of that edge. I know a similar situation can be implemented with Google Map API like the code below, but I can not find any source to help me implement the same thing in Leaflet.
google.maps.event.addListener(polygon, 'click', function (event) { console.log(event.edge) }
Google Map Documentation: https://developers.google.com/maps/documentation/javascript/reference/polygon#PolyMouseEvent
For those who come across this question: I found a solution myself!
I didn't find anything directly from Leaflet draw library that I could use, so I defined the problem for myself as a trigonometry problem and solve it that way.
I defined a function in which on polygon click, it converts the event.latlng and loops over polygon.getLatLngs()[0] taking a pair of A and B points. A is the first coordinates, B is the next and if it reaches to the end of array, B will be the first point. Then using Collinear Function of 3 points with x, y, I checked if the clicked x, y has a same slope as point A and B.(has to be rounded it up), if so, I would save that A and B point pair with their latLng information and further used it in my project.
Although this method works, I would appreciate if anybody would know a better solution or library built-in function that can be used instead. Thanks!
When the user clicks on the polygon you can loop through all corners and check if he clicked in the near of the corner.
poly.on('click', function(e){
var latlng = e.latlng;
var corners = poly.getLatLngs();
if(!L.LineUtil.isFlat(corners)){ //Convert to a flat array
corners = corners[0];
}
//Convert the point to pixels
var point = mymap.latLngToContainerPoint(latlng);
//Loop through each corner
corners.forEach(function(ll){
//Convert the point to pixels
var point1 = mymap.latLngToContainerPoint(ll);
var distance = Math.sqrt(Math.pow(point1.x - point.x, 2) + Math.pow(point.y - point1.y, 2));
//Check if distance between pixels is smaller then 10
if(distance < 10){
console.log('corner clicked');
}
});
});
This is plain JS you have to convert it self to angular.
A alternativ is to place on each corner a DivMarker or a CircleMarker and fire a event if the marker is clicked.
Looks like: https://geoman.io/leaflet-geoman

How to calculate location’s long/lat based on its bbox coordinates

please could anyone help?
I need to use a map.toFly() method to interpolate between 2 locations.
According to the Mapbox documentation, I need to pass in an object describing the destination I want to fly to. The object has to have a center property holding an array with centre Long/lat coordinates of the destination I need to be taken to.
https://docs.mapbox.com/mapbox-gl-js/example/flyto/
My problem with implementing the method is that I only have bounding box coordinates of the 2 locations between which I need to interpolate . I can’t do something like this:
map.flyTo(bbox)
Does anyone know how to obtain
centre Long/lat coordinates of each location based on their bbox coordinates?
Assuming you have 2 LngLatBounds objects you can call the getCenter() method.
var point1 = bounds1.getCenter();
var point2 = bounds2.getCenter();
where both bounds1 and bounds2 are objects of the type LngLatBounds.
Check:
https://docs.mapbox.com/mapbox-gl-js/api/#lnglatbounds#getcenter
Edit: for the values you gave in your comment it would be for the first bounds:
var sw1 = new mapboxgl.LngLat(110.2672863, -7.1144639);
var ne1 = new mapboxgl.LngLat(110.5088836, -6.9319917);
var bounds1 = new mapboxgl.LngLatBounds(sw1, ne1);
Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude).

Mapbox Overlapping Circles

Does anyone know a way to make overlapping circles in mapbox show the same color and only have the border around the outer edge display?
I have this:
And I made this in photoshop for what I want:
While I don't think there is a way to style all the circles to show their group outline, you can achieve the effect you want by creating a union of all the circle geometries and applying your style to that. Unfortunately, Leaflet's L.circle class offers no way to access a circle's geometry beyond the center point, and to perform a union, you need the path of the circle itself. Fortunately, there is Leaflet Geodesy and its LGeo.circle class, which produces circular polygons with a given radius and number of segments. Once you have these polygon representations of your circles, you can use turf.union to produce the outline you want.
Say you are starting with a layer of points called pointLayer (this can be a L.geoJson, L.mapbox.featureLayer, or any other class that inherits the .eachLayer method). You can then iterate over the features, creating a circular polygon for each of them and adding it to a temporary layer group, like this:
var circleLayer = L.layerGroup();
var radius = 5000
var opts = {
parts: 144
};
pointLayer.eachLayer(function(layer) {
LGeo.circle(layer.getLatLng(), radius, opts).addTo(circleLayer);
});
where radius is in meters and the parts option is the number of segments you want your polygons to have. Next, use the .getLayers method to get an array of all the layers in the temporary group, then iterate over that to create a union of all the features:
var circleUnion = unify(circleLayer.getLayers()).addTo(map);
function unify(polyList) {
for (var i = 0; i < polyList.length; ++i) {
if (i == 0) {
var unionTemp = polyList[i].toGeoJSON();
} else {
unionTemp = turf.union(unionTemp, polyList[i].toGeoJSON());
}
}
return L.geoJson(unionTemp, {style: unionStyle});
}
where unionStyle is whatever style you want to apply to your newly-combined circles. Here is an example fiddle showing all this with some random data:
http://fiddle.jshell.net/nathansnider/L2d626hn/

Unable to display only the points within a specific range (circle) using the .getBounds() function (Leaflet)

I am trying to display a certain amount of points within a specific range, that is within a circle. But when using the .getBounds() function for comparison to see whether the point is within the bound, i get some points outside it as shown in the screenshot below:
Map Screenshot
The code currently using to check if the point is within the circle bound is below:
echo '
var mark = L.marker([' . $r->coordinates[0]->longitude . ',' . $r->coordinates[0]->latitude . ']);
if(circle.getBounds().contains(mark.getLatLng())){
mark.addTo(map);
mark.bindPopup("'.$info.'");
}
';
I am looping into an array to retrieve the latitude and longitude and from there, to see whether the coordinates fills into the bound, if so, it adds it to the map with their corresponding popup
Any solution regarding this particular issue?
Thanks for helping
You can create your own contains method and add it to the L.Circle class because it doesn't have one by default. You can use the utility method distanceTo of the L.LatLng objects to calculate distance between your marker and the circle's center and compare that to the circle's radius:
L.Circle.include({
contains: function (latLng) {
return this.getLatLng().distanceTo(latLng) < this.getRadius();
}
});
Now when you have a circle and a marker or latlng object you can do this:
var map = L.map(...);
var circle = L.circle(...).addTo(map),
marker = L.marker(...).addTo(map);
latLng = L.latLng(...);
// Returns true when in the circle and false when outside
circle.contains(marker.getLatLng());
circle.contains(latLng);
Working example on Plunker: http://plnkr.co/edit/OPF7DM?p=preview
L.Circle reference: http://leafletjs.com/reference.html#circle
L.Marker reference: http://leafletjs.com/reference.html#marker
L.LatLng reference: http://leafletjs.com/reference.html#latlng
The method getBounds() always returns a rectangular area. Hence it can't be used for checking whether a non-rectangular object contains a given point.
For a circle you should be able to calculate the distance (distanceTo()) of the point to the circle's center (getLatLng()) and check whether it is smaller than the circle's radius (getRadius()). Note that the distance and radius are in meters.

How to get intersection area coordinates of two polygons on General Polygon Clipper(GPC)?

I'm using nutiteq library to draw polygons and getting the coordinates of the polygons with .getVertexList() command. Then I cast these coordinates to an array list . Then I cast these coordinates to another polygon list. GPC is calculating the intersection, union, XOR and difference areas integer values. Then I need to highlight the process area so I need processed areas coordinates but I can't get these coordinates directly from GPC.
The code I'm using for the area calculation is below. What should I do to get the coordinates of result polygon?. (I can't cast the coordinates directly by the way as you can see here...)
Thanks in advance.
public void IntersectionButton(View view) {
VectorElement selectedElement = mapView.getSelectedElement();
List<?> VisibleElements = selectedElement.getLayer().getVisibleElements();
ArrayList<Poly> polyList = new ArrayList<Poly>();
for (Object obj : VisibleElements) {
if (obj instanceof Polygon) {
Polygon poly = (Polygon) obj;
List<MapPos> geoList = poly.getVertexList();
Poly p = new PolyDefault();
for (MapPos pos : geoList) {
p.add(pos.x, pos.y);
}
polyList.add(p);
}
}
PolyDefault result = (PolyDefault) Clip.intersection(polyList.get(0), polyList.get(1));
int area = (int) (((int) result.getArea()) * (0.57417));
The result polygon seems to have all the methods you need:
getNumPoints() to get number of outer polygon points.
getX(i) to get X of specific outer polygon point, and getY(i) for Y.
getNumInnerPoly() to get number of holes in the polygon
getInnerPoly(i) to get specific hole. You iterate through hole similar way like outer polygon
You can construct new Nutiteq Polygon from this data, create list of MapPos for outer and list of list of MapPos for inner polygons (holes). What are values of X and Y, do they need further processing, is another question what you can investigate.