I am working with Leaflet.js library. I have an array of geographical points, described by latitude and longitude and a polygon, based on this points. How can i remove inner points of polygon and draw only it's outer border?
Array of points
[[53, 31], [51.4, 31.2], [51.3, 32] ... etc.] //it's length ~ 500 points.
Initializing map
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(mymap);
Setting polygon
L.polygon(points, {color: 'red'}).addTo(mymap);
This is what i have right now. Here is all of 500 points is shown.
Result i am expecting. Here all internal points are removed, showing the covered area.
Sounds like you are looking for a convex hull algorithm: it would provide you with the "envelope" of your Points.
You can use e.g. Turfjs: https://turfjs.org/docs/#convex
But note that it requires working with data converted to GeoJSON objects.
You can also have a look at how Leaflet.markercluster plugin has implemented it.
Related
I am using a Javascript library 'Tess2' to triangulate a series of contours.
https://github.com/memononen/tess2.js/blob/master/src/tess2.js
It generates a perfect 2d mesh of any shape consisting of multiple contours:
A contour consists of a series of points (in a negative winding order for solid fills, in a positive winding order for holes)
However, the resulting triangles output by the algorithm are no longer tied to a contour and its fill color.
How would I alter Tess2 (or any other javascript library that tesselates contours) to allow for the retention of color data in the resulting triangles?
I've tried looking everywhere and I cannot find a solution.
From what I've seen in the source code, the tessalation function contains a vertex indices in an returned object:
Tess2.tesselate = function(opts) {
...
return {
vertices: tess.vertices,
vertexIndices: tess.vertexIndices,
vertexCount: tess.vertexCount,
elements: tess.elements,
elementCount: tess.elementCount,
mesh: debug ? tess.mesh : undefined
};
You can create a new array with the colors for each vertex, and then use vertexIndices from the object to get a color of the vertex.
If you would like to have a color per face, you would just need to generate an array like above, which means putting the same vertex color for each vertex in a array. You would also like to wrap all of this data in some kind of convienent object or class.
[EDIT]
It turns out that the tesselation algorithm merges vertices in the same position, meaning that it reorganizes vertex array completely. There are a solution to explicitly not merge different contours with overlapping vertices:
Tess2.tesselate({ contours: yourContours, elementType: Tess2.BOUNDARY_CONTOURS });
That should preserve the original vertices, however not in an original order, use vertexIndices to get the original position of these.
After many failed attempts I finally got there.
I've been trying all this time to try and process a huge amount of contours all at once with a single tessellation pass.
I tried editing the tessellation library to make each half edge retain it original contour ID. I had several eureka moments when it finally seemed to work, only to be disappointed when I stress tested it and found it to be less than perfect.
But it turns out I've been incredibly daft...
All I had to do was group each contour with a particular fill, and then tesselate each group independently.
I didn't understand that for every interior contour fill, there would always be an opposite contour that effectively enclosed the outer contour loop.
For instance, to represent a red box with a blue box inside there would be 2 red contours and 1 blue. I thought it could be represented with only 1 blue contour and 1 red, where the blue would also represent the red contour's hole, and so processing each colour group of contours independently didn't make sense to me.
When I finally realised this, I figured it out.
I've published a solution on github but I'm not sure how much use it is to anyone:
https://github.com/hedgehog90/triangulate-contours-colour-example
I've included a pretty comprehensive exporter script for converting contours (including curves) into polygonal paths for Adobe Flash/Animate which might be useful for someone.
I will be writing an OBJ exporter on top of this shortly, so I can represent vector graphics in a 3D engine.
I have canvas object, and within it some image.
I also do have polygons defined as arrays of vertices, for example:
[ {x:50, y:50}, {x:50, y:150}, {x:200, y:100} ]
This is very simple polygon, some will be more complicated (currently the max is 10 points).
I'd like to either find a way to enumerate all pixels within the polygon, or just find average color of it.
Is there any library to do it? Or some clever algorithm?
As for comment re: getting image data by pixel - I know how to get color of a pixel. But what about getting it for all pixels within polygon?
I need to zoom my OpenLayers map (which uses a Google Maps baselayer) to fit all of a given list of coordinates into the view.
I've stored the coordinates in an array of longitude and latitude pairs named pointsDecimal which looks like this:
pointsDecimal: Array[50]
0: 148.77638
1: -34.491728
2: 148.77896
3: -34.492302
4: 148.778090711323
...
Even-numbered indices (0, 2, 4 etc) are longitude, and odd-numbered indices (1, 3, 5 etc) are latitude.
This is the code I'm trying to use:
map.getView().fit(pointsDecimal, map.getSize());
But for some reason this puts me at maximum zoom level at the coordinates [0,0] - in the Gulf of Guinea, not in southeastern New South Wales where I'd like to be!
I know this would be much easier if I was using an OpenLayers source (e.g. source.getExtent()) in place of my pointsDecimal array, but this is not an option in this case for reasons I won't go into right now - I can only use the array.
Can anyone give me any hints please?
EDIT: I think I'm nearly there, thanks to Anupam. This is what I have now:
var extent = [pointsLongMin,pointsLatMin,pointsLongMax,pointsLatMax];
map.getView().fit(extent,map.getSize());
The values I'm passing to the array are as follows:
pointsLongMin: 148.771162
pointsLatMin: -34.5029736405108
pointsLongMax: 148.77896
pointsLatMax: -34.491728
But I'm still getting dumped out in the ocean at [0,0]. What am I doing wrong here?
In order to use map.getView().fit(extent,size).
extent denotes four points as [minx, miny, maxx,maxy].
It is actually a rectangle. try
var extent=[148.77638,-34.491728,148.77896,-34.492302];
map.getView().fit(extent,map.getSize());
most propable reason is that your map is projected on EPSG:3857while your extent EPSG:4326. So you need to transform your extent to your map projection.
var coordMin = ol.proj.fromLonLat([148.77638,-34.491728], 'EPSG:3857');
var coordMax = ol.proj.fromLonLat([148.77896,-34.492302], 'EPSG:3857');
var extent=[coordMin[0],coordMin[1],coordMax[0],coordMax[1]];
map.getView().fit(extent,map.getSize());
You may find a more elegand way to do the extent transformation. Unless you provide your full code we can only guess what is your map projection. I am just guessing is EPSG:3857 cause thats the default ol3 use.
I am trying to draw polygons on a map, using OSM data downloaded. I have written a query that returns a list of polygons from the planet_osm_polygon table. It resturns the list as JSON objects. I am using gl.drawArrays(gl.LINESTRIP, 0, json_data_length) to draw the polygons. I have done the same for points- I have a list of points returned and I have been able to plot them using gl.POINTS.
The problem is, I want each of the polygons to be drawn separately, but I guess using LINE_STRIP is connecting one ending point of one polygon to the starting point of another polygon.
For example, I want civic center plaza and buchanan street in SFO to be separate polygons. But the polygons, after being drawn, are still connected to each other through one point. I want these two to be drawn as separate polygons. How do I do it?
I do not want to use any libraries. Just basic WebGL. My JavaScript code takes the lat-long coordinates from my osm database and converts into pixel coordinates to help plotting- see link: WebGL shader code (http://psousa.net/demos/webgl/) I am using this example and extending it.
If i understood correctly you want to draw 'borders' of multiple polygons not the filled polygon itself.
In order to draw seperate lines in a single draw call you should use gl.LINES mode instead of gl.LINESTRIP.
Lets say you have a quad which has points A,B,C,D and a triangle which has points X Y Z. If you want to use glDrawArrays command with GL_LINES mode , your vertex data should be submitted as
{A,B, B,C, C,D, D,A, X,Y, Y,Z, Z,X}
Following lines are drawn with this vertex data
Line from A to B
Line from B to C
Line from C to D
Line from D to A
Line from X to Y
Line from Y to Z
Line from Z to X
In order to eliminate duplicate vertex data you can also use glDrawElements with a proper index .
I have used the code in the following :
http://www.amphibian.com/blogstuff/collision.html. in the html test file I have changed the the first triangle to
triangle1.addPoint({"x":-20, "y":-20});
triangle1.addPoint({"x":-20, "y":20});
triangle1.addPoint({"x":20, "y":20});
triangle1.addPoint({"x":20, "y":10});
triangle1.addPoint({"x":10, "y":10});
triangle1.addPoint({"x":10, "y":-20});
now when I move the other triangle with inside this shape before crossing it gives me wrongly intersection. Any idea where could be the problem?
All right, I set up a fiddle for anyone else wanting to play with this. Here are the results:
The script makes use of the Separating Axis Theorem or (as Wikipedia calls it) Hyperplane separation theorem, as explained in the source of polygon.js:
/*
* To detect intersection with another Polygon object, this
* function uses the Separating Axis Theorem. It returns false
* if there is no intersection, or an object if there is. The object
* contains 2 fields, overlap and axis. Moving the polygon by overlap
* on axis will get the polygons out of intersection.
*/
Polygon.prototype.intersectsWith = function(other) {
This theorem only applies to convex polygons. Your shape is not convex as it has a "dent" in it. That's why the script incorrectly reports that the shapes are intersecting. If you need to make it work with concave shapes, you'll have to make it first split the concave shape up in separate convex parts and then apply the theorem to all individual parts. Obviously, this makes the script more complex as you need to iterate over the cross product of the concave parts of two shapes.
Here is my not too complicated implementation of finding the intersection polygon of two polygons.
It works for convex and concave polygons, but not for complex (self-intersecting) polygons.
Algorithm is fairly similar to the one presented in Margalit & Knott.
Its complexity is about 4*n1*n2, where n1 and n2 are numbers of vertices in polygons whose intersection is being calculated.
It is a single standalone .js file. A 'Polygon' is regarded any javascript array of 2D Points. A 'Point' is any javascript object with x and y numeric properties.
Implementing the Union functionality on top of existing one should not be a problem and I will do it probably soon.
Intersection of 2D polygons