Displaying Antarctica using GeoJSON in heremaps - javascript

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]

Related

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

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.

Slow updating HereMaps DomIcon when location (lat / long) changes, re-render

Using renderToStaticMarkup to render html to a DomIcon in HereMaps. That's working and quick when there's not that many markers and updates. However, 100 markers frequently updating and re-rendering is causing a slow page open. It's even slowing the map render.
I've looked into best practices around re-using a DomIcon. I've also been looking into clustering -- but not sure how updating would work. Is clustering the only way to go further here? Curious if there's any other best practices for performance
Clustering solves the potential performance issues, however H.map.Group is used to associate the markers together and the group.getBounds() method to find the minimal bounding box holding all of the group's contents. The map.viewBounds() can then be updated.
function addMarkersAndSetViewBounds() {
// create map objects
var toronto = new H.map.Marker({lat:43.7, lng:-79.4}),
boston = new H.map.Marker({lat:42.35805, lng:-71.0636}),
washington = new H.map.Marker({lat:38.8951, lng:-77.0366}),
group = new H.map.Group();
// add markers to the group
group.addObjects([toronto, boston, washington]);
map.addObject(group);
// get geo bounding box for the group and set it to the map
map.getViewModel().setLookAtData({
bounds: group.getBoundingBox()
});
}
forEachDataPoint (callback)
This method invokes the specified callback for each data point in the given cluster which can work for updating the data points.
A clustering algorithm groups data points by collapsing two or more
points positioned close to one another on the screen into a single
cluster point. All other (not collapsed) points are still visible on
map as noise points.
If this actually suits the use case, go for clustering. It helps to uplift the performance issue. for more details refer :
developer.here.com/documentation/maps/topics/clustering.html

How to get Leaflet GeoJSON feature containing a given latitude/longitude point

I have a LeafletJS map with a GeoJSON layer that contains multiple polygons. If a user enters a latitude/longitude coordinate that falls within the GeoJSON layer, the script should retrieve the feature that contains that point and log some information about it to the console.
I can't simply use Leaflet's built-in event handling because the latitude and longitude coordinates are generated by a separate input field, not by direct interaction with the map. So my question is not a duplicate of this.
I'm looking for something similar to getFeatureContainingLatLng() in the example below:
var map = L.map('map');
var geojson = L.geoJson(myGeojson);
geojson.addTo(map);
$.on('address input changed event', function(lat, lng) {
var myFeature = geojson.getFeatureContainingLatLng(lat, lng);
console.log(myFeature.properties);
});
The plugins Leaflet.CheapLayerAt or Leaflet-pip should help. Both approaches will solve your problem, albeit they have different advantages and disadvantages specially in terms of algorithmic complexity.

Setting the selected layer on a Leaflet/Mapbox L.Control.Layers

I have a map with a few base layers. Users can choose the base layer and then save the map. After saving the map, the system loads it with the new base layer. That base layer should be selected in the L.Control.Layers control. However, there's no way in the API to select a base layer.
Anyone knows a way around this, or a different plug in?
UPDATE: Here is the code I use. MapConfigs has the ids in MapBox, and can create the map that L.control.layers requires.
var map = L.mapbox.map( components.mapDivId , MapConfigs.idFor(baseLayerName) );
map.addControl( L.control.layers(
MapConfigs.toBaseLayersControlMap(map)
).setPosition("topright"));
Thanks!
Why not store references to all the base layers available in a hash, then use addLayer or removeLayer (http://leafletjs.com/reference.html#map-addlayer) as needed to programmatically select base layers?. Something like below.
var tileLayers = {light: L.tileLayer('lightUrl'),dark: L.tileLayer('darkUrl')}

Google Maps v3 API - Drawing Circles on Map

What I'm trying to do is draw a circle on google maps and retrieve the latitude/longitude/radius to store in a database, alternatively a geometry object would also be fine.
Using the standard code from https://developers.google.com/maps/documentation/javascript/examples/drawing-tools i created the map and drawing toolbox. What i can't seem to do is get the lat/long/radius from the map using javascript, surely this must be possible.
Any ideas?
Thanks
Note - my code is identical to the google example, i figured it was better to link to it rather than copying ~60+ lines of html into a post.
Thanks
Ref: https://developers.google.com/maps/documentation/javascript/drawing
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
var radius = circle.getRadius(),
center = circle.getCenter();
});
Edit: getCenter()

Categories

Resources