Leaflet.js: Only show specific countries, dim or hide the rest - javascript

Based on: Dim/Hide rest of map around country with leaflet.js
While the accepted answer was almost spot on, its JSFiddle demo only works for old single polygon GeoJSON. Modern multipolygon GeoJSON allows for additional shapes to make up for overseas territories etc., and thus also introduces extra arrays which the JSFiddle demo doesn't know how to handle:
// transform geojson coordinates into an array of L.LatLng
var coordinates = france.features[0].geometry.coordinates[0];
var latLngs = [];
for (i=0; i<coordinates.length; i++) {
latLngs.push(new L.LatLng(coordinates[i][1], coordinates[i][0]));
}
L.mask(latLngs).addTo(map);
I realize this is all basic JavaScript and array 101 stuff, but would anyone happen to know how to make the above code work with the additional arrays from multipolygonal GeoJSON?
Multipolygon example from https://geojson-maps.ash.ms/: https://jsfiddle.net/uc81esy5/
Single polygon example used in the accepted answer: https://jsfiddle.net/r9m4t3d7/

I guess that by "modern GeoJSON" you mean "GeoJSON features of type Polygon with an outer ring but also with inner rings". So this is really about "How do I convert a GeoJSON multipolygon geometry to an array (rings) of arrays (points in a ring) of arrays (Leaflet LatLngs)?".
Please note that the concept of polygons with inner rings is by no means "modern": it does appear in the (now deprecated) 2008 GeoJSON specs, which in turn take heavy inspiration from OGC's Simple Features which date back to 2003.
I would leverage the coordsToLatLngs static method of L.GeoJSON already implemented by Leaflet. e.g.:
var latlngs = L.GeoJSON.coordsToLatLngs(feature.geometry.coordinates, 1);
Remember to perform a sanity check on geometry.type if neccesary; the levelsDeep parameter shall be 0 for LineStrings, 1 for MultiLineStrings and Polygons, and 2 for MultiPolygons.

Related

What is the Ideal way to create a Triangle-Coordinates in Google Map API with two location points consisting of latitude & longitude

I have a scenario in my JavaScript application where I have the coordinates of a starting point which consist of Latitude and Longitude, similarly an ending point with it's respective coordinates.
Now I need to search for a location which basically provides with a set of coordinates and find if the recently entered location lies in between the previously mentioned starting point or ending point. However, the location does not need to match exactly within the points of the path of the start and end point. That is even if the location lies around the distance of say 2-3 km from the derived path, it should give a match.
I believe that we can create a triangle by providing three coordinates i.e start-point, end-point and a third point. So once the triangle is formed we can use google.maps.geometry.poly.containsLocation method to find if our searched location is present inside this triangle.
So my question is how can we get a third point to create a triangle which will provide locations that are nearby within 2-3 km from start to end point.
Else is there any alternate approach to deal with my use case?
Use googlemap's geometry library
This function specifically
isLocationOnEdge
Here's an example
0.001 tolerance value would be 100m
var isLocationNear = google.maps.geometry.poly.isLocationOnEdge(
yourLatLng,
new google.maps.Polyline({
path: [
new google.maps.LatLng(point1Lat, point1Long),
new google.maps.LatLng(point2Lat, point2Long),
]
}),
.00001);
Please note that the following answer assumes Plane Geometry where you should be using Spherical Geometry instead. Although this will be fine for less accurate purposes (like approximate distance, etc..)
It seems more of a geometry question than a programming question. A triangle like you mentioned won't be able to cover a straight line path in a uniform way. The situation can be thought of more like a distance between point and a line problem (Refer the given diagram
Here you can just find the distance between point C and line AB which you can check whether it's below 2.5 KMs (I've omitted all the units and conversions for simplicity)
Please note that you will also need to convert the distances from radian to appropriate units that you require using haversine formula, etc. which is not a trivial task (https://www.movable-type.co.uk/scripts/latlong.html).

Is There Any Function or Algorithm For [Draw a Feature Surrounds Another Feature]?

I have to use OpenLayers to create a logic that draws two Features.
After the user draws Feature A,
We need logic to draw Feature B that surrounds the Feature A outside.
Draw Feature A on a map.
After Feature A is drawn, the system must create Feature B that surrounds Feature A.
The final result should be the same as Image.
PRECONDITION
Feature can have 3 - 6 angles.
The length of each side is unpredictable.
The angle of each side is unpredictable.
All sides of Feature B must be made from all sides of Feature A with the distance specified by the user.
How do we solve this problem?
full source code : https://github.com/JeahaOh/OpenLayersStudy/tree/master/Examples/EffectiveRange/CDN
Hey this looks like creating a geometry with a buffer of x (x is defined by the user).
You can use JSTS to create buffers from a geometry and then map it back to an openlayer geometry.
OpenLayers example that draws geometries with a buffer. This example uses LineString geometries but you can use any geometry.
Looking at your example you probably want sharp edges on your outer geometry so you can use a mitre line join style
var bufParams = new jsts.operation.buffer.BufferParameters();
bufParams.setJoinStyle(
jsts.operation.buffer.BufferParameters.JOIN_MITRE)
var outer = inner.buffer(spacing, bufParams);
See docs for BufferParameters for more options.
Here is a jsfiddle that shows it.

Displaying Antarctica using GeoJSON in heremaps

I'm trying to render Antarctica geojson shape on a map using the HERE maps api.
The geojson is found here: https://github.com/johan/world.geo.json/blob/master/countries/ATA.geo.json
You can see github renders it nicely.
Using the same geojson on geojson.io also renders it nicely.
But somehow it seems to render the 'inverse' of Antarctica when using it in HERE maps.
It colors everything except antarctica.
see: http://imagebin.ca/v/1dZIn5vsEuFx
(I've tried making an expample using jsfiddle, but it's not able to load external json. And the HERE maps api doesn't allow you to load geoJSON from a string)
Is there an issue with the geoJSON? Is there an issue with the HERE maps api?
The API doesn't quite understand what to do with the open polygon. Because the polygon is basically just a line around the globe the API doesn't know if you shape closes over the north pole or the south pole. By default it assumes that open polygons close over the north pole. You can change this by using this flag (setNorthPoleCovering):
http://developer.here.com/javascript-apis/documentation/v3/maps/topics_api_nlp/h-map-polygon.html#h-map-polygon__setnorthpolecovering
However, actually getting to that point in the code where this can be done is a bit complicated:
// When you instantiate the geojson.Reader you can specify a function that
// receives all objects the reader parsed. It is called when objects are
// being rendered on the map. At that point we can look into the object and
// check whether it is Antarctica
var reader = new H.data.geojson.Reader('...ATA.geo.json', {
style: function(obj) {
if (obj.getData().properties.name === "Antarctica") {
//AHA! We found Antarctica!
// Since this is a multi-polygon we have a group here which contains
// all polygons. We apply the north-pole-covering flag to each of the
// polygons
obj.forEach(function(polygon) {
polygon.setNorthPoleCovering(false);
});
}
}
});
reader.parse();
map.addLayer(reader.getLayer());
Depending on what you want to accomplish in terms of dynamic behavior, if you are just looking to display or share a map with cards and other metadata about a country with some basic styling -- HERE XYZ can be used to render GeoJSON on a HERE map.
If you want to do it with JavaScript rather than an embedded iframe, the other answer may be what you are looking for.
There is an there an issue with the GeoJSON, and other mapping APIs would have the same problem. It needs to be closed at the 180th meridian, so
[178.277212,-84.472518],[180,-84.71338],[-179.942499,-84.721443]
becomes
[178.277212,-84.472518],[180,-84.71338],[180,-90],[-180,-90],[-180,-84.71338],[-179.942499,-84.721443]

Node.js/Javascript library to test if point is in geojson multipolygon

Is there some library for node.js or javascript in general that provides a function to check if a coordinate is in a geojson multipolygon?
I'm trying to create a small HTTP API that tells me which multipolygons (representing countries, counties, cities, etc.) contain a given coordinate.
I thought that I'll hold a list of all multipolygons & their bounding-box in memory and then first check for each polygon if its bounding box cointains the coordinate. If yes, then it'll check if the coordinate is in the multipolygon itself.
I know there's a library called "clipper" that got ported to javascript, but it seems that the library does not provide a simple "pointInPolygon" function, even if the library itself is very powerful.. Is it still possible with this library?
Additionally, I've found another library called "geojson-js-utils" but it does not seem to support multipolygons (at least it's not mentioned there)
I've found some other libraries that can check if a point is in a polygon, but I don't know how to use them to check if a point is in a multipolygon.
Any hints?
In newest Clipper there is an efficient PointInPolygon function. It uses algorithm The Point in Polygon Problem for Arbitrary Polygons by Hormann & Agathos.
The documentation of Javascript Clipper's PointInPolygon function says:
ClipperLib.Clipper.PointInPolygon()
Number PointInPolygon(IntPoint pt, Path poly)
Returns 0 if false, -1 if pt is on poly and +1 if pt is in poly.
Usage:
var poly = [{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}];
var pt = new ClipperLib.IntPoint(50,50);
var inpoly = ClipperLib.Clipper.PointInPolygon(pt, poly);
// inpoly is 1, which means that pt is in polygon
To test multipolygon, you can traverse subpolygons and check them using PointInPolygon.

how to get longitude & latitude of line in openlayers

I am getting line latitude & longitude as
LINESTRING(1491215.4689647 6893983.2031826,1494163.0718675 6894785.7919795)
after seeing this solution.
how to get points return from OpenLayers.Control.DrawFeature
Now what I want to do is that I want to display start point & end point on my web page.
So how can I extract latitude & longitude from here so that I can show it in my page.
If your linestring is already in OpenLayers, there is no reason to convert it to WKT. Linestring geometry contains array of Points. You can access components of geometry in several ways, for example:
drawControls[key].events.register('featureadded', drawControls[key], function(f) {
// First point
var firstPointGeom = f.feature.geometry.components[0].clone();
// Last point
var secondPointGeom = f.feature.geometry.components[f.feature.geometry.components.length - 1].clone();
// Now you got geometries, let's create features from them...
var firstPointFeat = new OpenLayers.Feature.Vector(firstPointGeom);
var secondPointGeom = new OpenLayers.Feature.Vector(secondPointGeom);
yourVectorLayer.addFeatures([firstPointFeat, secondPointGeom]);
});
Pay attention - this works with LineStrings. Probably it's not necessary to go into detail about clone(), it's up to particular use case, whether you need it, or you can use just var firstPointGeom = f.feature.geometry.components[0];
Thats WKT format, you're looking at. You'll potentially need to reproject those coordinates to the target projection if they are not in the same projection. After than, you should be able ot ask openlayers for the points of any given geometry using the base geometry functionaily. Get the point array from the linestring instance and iterate over it. Make sure you know the right coordinate order for your projection / data model.
Hope that helps!

Categories

Resources