Finding Self-Intersections in Leaflet polygons using JSTS Library - javascript

I'm using Mapbox with Leaflet Draw, and I would like to avoid self-intersecting polygons.
I can already specify to not allow intersections while creating the draw control, but it only works when I use the control to create a new polygon. However, if I try to edit an already existing polygon, it allows intersections over there.
I searched around and found the JSTS Library which does exactly what I want, and I also found this JSFiddle to use as an example, where it works based on the Google Maps API.
So I created my own JSFiddle with Mapbox based on the above two links. Here, the 'findSelfIntersects' function kicks in if it's a polygon edit, and it is not used if it is a new polygon. The idea is that, if there's an intersection, I'll show an alert to the user and cancel the edit. However, when I try to do this, I'm getting an uncaught exception: [object Object] error.
The error seems to be formed on this line of the findSelfIntersects function:
var shell = geometryFactory.createLinearRing(coordinates);
I checked out the coordinates returned by the Google Maps example, and that does seem similar to the coordinates I'm getting. But I'm not sure why I'm getting this error.

I just noticed that in the Google Maps example, the starting and ending points were the same in the coordinates array, whereas mine weren't. I had missed it initially. Now I've added the below code after the 'for' loop, and it works fine.
coordinates.push(new jsts.geom.Coordinate(
corners[0].lat, corners[0].lng));
This is an updated JSFiddle in case anyone wants to use the JSTS library with Mapbox/Leaflet.

Related

Editing a shapefile uploaded using leaflet.shapefile

I'm using Mapbox with Leaflet for drawing, editing and removing polygons etc. There might also be a case in which the user might have zipped shapefiles and want to use that directly, instead of drawing the polygons. So I'm using leaflet.shapefile to upload shapefiles and add them to the map.
But when I try to edit the shapefiles using the Leaflet Draw control, I get an error telling me that "i.editing is undefined". I tried converting the layer to GeoJSON before adding it to the featureGroup just in case (like in the code below), to see if that had any effect, but it didn't.
var layergeojson = layer.toGeoJSON();
featureGroup.addLayer(layergeojson);
This is a jsfiddle of what I have right now. I tried researching online to see any similar cases, but I'm not able to find any.
Is it possible to edit the uploaded shapefiles using the Leaflet Draw control?
When you do var layergeojson = layer.toGeoJSON(), the layergeojson now contains a plain GeoJSON object, not a Leaflet layer.
Therefore, featureGroup.addLayer(layergeojson) should throw an error (open your browser console). Instead, you should probably use the .addData() method: featureGroup.addData(layergeojson).
As for editing your resulting layers, it might be related to this: https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet/203773#203773

Using Google Maps API with custom tiles

So, basic gist is, I have my own tiles of not the real world I'd like to display with the Google Maps viewer. I've found examples of how to split an existing single image into tiles for use with it, but nothing that deals with setting up your own tiler.
I have map data such as this:
https://dl.dropboxusercontent.com/u/44766482/superimage/index.html
Which right now is just a bunch of 1600x1600 images in an html table. This naive method works, but I'd like to switch to the more robust google api for better zooming and smarter streaming of the image data.
I've been unable to find a good example of how to generate your own tiles for the zoom levels and bring it together with some html/js.
If you want some more information for the goal process;
I have a python script that can output any size tiles of the map, at any zoom level. I'd like to bundle those together into a google maps api website. But in my own efforts I have not found a good example or documentation of how to do that. For one, I can only find examples of how the zoom levels work for the real world map, but not for a custom one.
Edit:
Got most things working as I want them, but I'm still confused regarding the "center" that can be set, as it's in lat and lng, which don't apply. I'd also like to set boundaries as currently it tries to load .png files outside of the maps range.
My current progress:
https://dl.dropboxusercontent.com/u/44766482/googlemapspreview/index.html
I think what you are looking for is the google maps imageMapTypes:
https://developers.google.com/maps/documentation/javascript/maptypes#ImageMapTypes
Basically, each zoom level is the 4 lower zoom tiles combined. A Projection function can be skipped to get orthogonal mapping.

Javascript polygon selector, polygon brush

I need a 'polygon' selector type functionality. Basically, the ability to drag lines to form multiple polygons; pref with the ability to edit the 'points' of the polygon after the shape has been 'closed' (but that's secondary) and/or move the polygons...
I generally dislike 'reinventing the wheel' and I figured I'd find tons of examples to work with, but I was wrong...
The polygon tool in Google Maps is just about perfect, but has anyone utilized it outside of GMaps? (I recall it required a GMap as an attribute from my work with Google Maps). Before I roll up my sleeves, I just want to ensure there isn't something already made (this is a very small part) - so if (a) Google Maps Polygon object is usable without a map, or (b) there's another library/project I'm missing please let me know.
Fabricjs is an option you can check.
Have a look at D3.js which has a great api for visualizing data and geo information. Besides the standard one-/two-dimensional brush there are plugins for more advanced types of brushes:
Polybrush. Providing a polygon brush.
lasso. Lassoing a selection by freely drawing a line path.

Draw line on Map and get countries line passes through using javascript

I'm working on a maps based application and at the moment want to do the following. I have two coordinates a start point and an end point and can draw a line between those points on a map. However what I want to do is to be able to get a list of all countries on the map that the line passes through. I was wondering if this can be done using google maps. I've looked at a number of options but can't get around the way to get this done - how do I do this?
you could check at various points of the line for the country it's in with:
pOfLine.AddressDetails.Country.CountryName

Google Maps Points do not appear until low zoom levels

I'm working on a (Perl) program that uses the Google Maps API and a KML file to pull data from a database that creates points on the map. I have that much done, but the points only appear after I zoom pretty much all the way in, to a zoom level where only one point is showing.
The default zoom only shows my small city (3-5 miles) so I thought all the points would be able to show. Does anybody know how to get all of the points to show up at city-wide level as opposed to only showing up when zoomed all the way in?
Any help is greatly appreciated. Thanks!
Edit: Added a JavaScript tag because I've seen a lot of work done with Google Maps using JS, and considering the problem really isn't language-specific, I figured some of those developers might be able to offer some insight.
Try to incorporate the <Lod> tag in your KML, which is child of a <Region>. You can define this once per placemark you get from your DB. or only once per query (defined by minLat, maxLat, minLong, maxLong). In the first case the LodPixels is a constant whereas in the latter case you must calculate it as a function of the region size. It sure works in Google Earth and may work as well in Maps. Look here to see it work in Earth API (JS)
....
<Region>
<LatLonAltBox>
<north>###</north>
<south>###</south>
<east>###</east>
<west>###</west>
<minAltitude>###</minAltitude>
<maxAltitude>###</maxAltitude>
</LatLonAltBox>
<Lod>
<minLodPixels>###</minLodPixels>
<maxLodPixels>###</maxLodPixels>
<minFadeExtent>###</minFadeExtent>
<maxFadeExtent>###</maxFadeExtent>
</Lod>
</Region>
....

Categories