Error when using Circle getBounds() and contains() - leaflet

I'm getting the error below when trying to run getBounds() and contains() with a Circle shape.
leaflet.js:7 Uncaught TypeError: Cannot read property 'layerPointToLatLng' of undefined
I'm able to use it with the other shapes, but the circle is being stubborn. I tried this solution from another question, but no success.
Here's the code I have for the polygon and rectangle shapes:
drawnLayers.eachLayer(function(l) {
if (type == 'circle') {
// console.log(l.getBounds().contains(layer.getBounds()));
} else {
if (l.getBounds().contains(layer.getBounds())) {
isDonut = true;
l._latlngs.push(layer.getLatLngs());
l.redraw();
$('#map-info').append("<br>New Polygon: <pre>" +
JSON.stringify(l.getLatLngs(), null, 2) + '</pre>');
}
}
});

l.getBounds().contains(layer.getBounds())
getBounds() is a method specific only to polyline/polygon/rectangle in leaflet 0.7.x
It was added to circle shapes as of version 1.0.0 - see leaflet reference versions
To solve the problem you have 2 options
use some other methods for circles like getRadius() and compute by yourself if the shape contains your other shape
upgrade your leaflet library
Personally I would upgrade the leaflet library to 1.0.3 (which I did very easy and without any compatibility issues on my project)

Related

Dynamically remove Mapbox 3D terrain in Mapbox-GL

I'm using mapbox-3d-terrain with the new version of mapbox-gl. We want to give our users the option to switch back to 2D. I would like to be able to
unset Terrain
then remove the source
This is the function to switch it 'on'.
// manage 3D terrain
enable3DTerrain() {
try {
this.map.addSource('mapbox-dem-2', {
"type": "raster-dem",
"url": "mapbox://mapbox.mapbox-terrain-dem-v1",
"tileSize": 512,
});
this.map.setTerrain({ "source": "mapbox-dem-2", 'exaggeration': 1.5 });
} catch (e) {
console.log({ e });
}
},
Is there a map function for unsetting terrain? Currently I am restarting / rebuilding / reloading the map completely to remove the 3D terrain, which is not how I want to implement my solution.
I found a simple solution how to switch map back to 2D:
this.map.setTerrain();
It works without restarting or reloading.
Then you can remove the source, and add it again if necessary.
I was dealing with the same use case. After playing around,
I found that changing {'exaggeration': 0} value to 0 in
this.map.setTerrain({ "source": "mapbox-dem-2", 'exaggeration': 1.5 })
displays the 2D view of the map.
If elevation of the map exists, set maxPitch: 0 or pitch: 0 in your initialViewState or viewState of the map conditionally to toggle between 2D & 3D.

How to show current location indication

I'm using the Flutter SDK Version 4.3.1.0.
I get my location updates from the geolocator plugin and want to show the location on the HERE map. It correctly centers the map to the current location but there is no location indicator.
I currently use the following code. What else do I need?
void _showPosition(final GeoCoordinates coordinates) {
_mapView.mapScene.loadSceneForMapScheme(MapScheme.greyDay, (MapError error) {
if (error != null) {
print("Map scene not loaded. MapError: " + error.toString());
return;
}
_mapView.camera.lookAtPointWithDistance(coordinates, 1000);
});
}
I'm using the Flutter Channel beta, v1.17.0-3.4.pre
The HERE SDK for Flutter does not contain a pre-configured location indicator. You can easily create one by adding a circle item onto the map:
For this I would recommend using a MapPolygon that contains a GeoCircle shape. You can then also update the radius of the GeoCircle on the fly to indicate the current horizontal accuracy of the geolocator plugin.

Bing Maps V8 SDK - Get drawn shapes

I have a Bing map with drawing manager enabled for users to draw shapes (mostly one polygon at a time). I want to be able to get the details of the drawn polygon so I can save it in the database.
The below function can access the shapes but returns the coordinates only
function getShapes()
{
var shapes = drawingManager.getPrimitives();
if (shapes && shapes.length > 0)
{
var rings = shapes[0].getRings();
alert('Retrieved ' + rings[0] + ' from the drawing manager.');
}
else
{
alert('No shapes in the drawing manager.');
}
}
result is:
Retrieved [MapLocation (35.17314901376581, 44.72432011035158)],[MapLocation (35.10324034213123, 44.73015659716798)],[MapLocation (35.12346106720259, 44.90525120166017)],[MapLocation (35.18633788986748, 44.88362186816408)],[MapLocation (35.17314901376581, 44.72432011035158)] from the drawing manager.
How can I get the exact drawn shape details not just the coordinates?
Remove getRings() and you will have the shape object. The Get Rings function retudrrns the coordinates of a polygon.

Handdrawn Lines for Highcharts

How would you extend Highcharts to accomplish a "hand-drawn" effect (example: https://www.amcharts.com/demos/column-and-line-mix/?theme=chalk ).
Or can it be done using a library?
Implementing that in Highcharts requires some core code analyzing and wrapping/overwriting SVGRenderer methods.
Example
Column points are SVG rect's shapes:
https://github.com/highcharts/highcharts/blob/master/js/parts/ColumnSeries.js
translate function:
// Register shape type and arguments to be used in drawPoints
point.shapeType = 'rect';
drawPoints function:
point.graphic = graphic =
renderer[point.shapeType](shapeArgs)
.add(point.group || series.group);
SVGRenderer (https://github.com/highcharts/highcharts/blob/master/js/parts/SvgRenderer.js) contains rect method that can be wrapperd/overwritten so that it returns the complex path (handwritten effect) instead of simple rect tag.
Docs about wrapping/overwriting: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

Check if coordinates are inside a KML polygon

I have a KML file which defines a region (or polygon). I would like to make a function that checks if a given coordinate is inside or outside that polygon.
This is the KML if you want to take a look: http://pastebin.com/LGfn3L8H
I don't want to show any map, I just want to return a boolean.
Point-in-polygon (PiP) is a very well-studied computational geometry problem, so there are lots of algorithms and implementations out there that you can use. Searching SO will probably find several you can copy-paste, even.
There's a catch, though—you're dealing with polygons on the surface of the Earth... which is a sphere, not the infinite Euclidean plane that most PiP algorithms expect to work with. (You can, for example, have triangles whose internal angles add up to greater than π radians.) So naively deploying a PiP algorithm will give you incorrect answers for edge cases.
It's probably easiest to use a library that can account for differences between Euclidean and spherical (or, more precisely, Earth-shaped) geometry—that is, a mapping library like MapKit. There are tricks like the one in this SO answer that let you convert a MKPolygon to a CGPath through map projection, after which you can use the CGPathContainsPoint function to test against the flat 2D polygon corresponding to your Earth-surface polygon.
Of course, to do that you'll also need to get your KML file imported to MapKit. Apple has a sample code project illustrating how to do this.
This can be done with GMSGeometryContainsLocation.
I wrote a method that makes use of the GoogleMapsUtils library's GMUKMLParser.
func findPolygonName(_ location: CLLocationCoordinate2D) {
var name: String?
outerLoop: for placemark in kmlParser.placemarks {
if let polygon = (placemark as? GMUPlacemark)?.geometry as? GMUPolygon {
for path in polygon.paths {
if GMSGeometryContainsLocation(location, path, true) {
name = (placemark as? GMUPlacemark)?.title
break outerLoop
}
}
}
}
if let n = name, !n.isEmpty {
locationLabel.text = n
} else {
locationLabel.text = "We do not deliver here"
}
}
This function iterates over the polygon and its path to determine whether the given coordinates are within the path.