leaflet js: draw POIs as canvas - javascript

I want to draw many geo points with Leaflet. Therefore I want to use HTML5 canvas to improve the performance.
My datasoure is geoJSON. As I saw in the documention of Leaflet, it is not possible to draw the geo positions as canvas yet.
var anotherGeojsonLayer = new L.GeoJSON(coorsField, {
pointToLayer: function (latlng){
return new L.Marker(latlng, {
icon: new BaseballIcon()
});
}
});
I think I should hook up here:
pointToLayer: function (latlng) { }
Does somebody know how to draw my latlng objects as canvas?

I'm Leaflet author. You can do this by using L.CircleMarker instead of regular Marker, and also using an experimental L_PREFER_CANVAS switch to render vectors as Canvas (instead of SVG), like this: https://github.com/CloudMade/Leaflet/blob/master/debug/vector/vector-canvas.html

Expanding on the original answer in case anyone needs this for Leaflet 1.0. You should still use L.circleMarker() (Leaflet circleMarker documentation) instead of L.marker(), but the way to use the canvas has changed.
In Leaflet 1.0, the experimental L_PREFER_CANVAS switch has been upgraded to an official map option preferCanvas (Leaflet preferCanvas documentation).
var map = L.map('mapid', {
preferCanvas: true
});
Alternatively, you can explicitly set the canvas renderer; I think this does the same thing as the preferCavas option. Here's the Leaflet documentation for canvas.
var map = L.map('mapid', {
renderer: L.canvas()
});
Either of these options (preferCanvas: true or renderer: L.canvas()) with L.circleMarker() was significantly faster than a regular layer using L.marker().

Related

Is using leaflet with Mapbox GL JS possible?

I'm attempting to use leaflet layers on a project using a mapbox GL JS map. Mapbox offers two different ways to instantiate a map, and all the leaflet examples are using the 'classic' Mapbox API. I've build a whole experience using the GL JS way (seemed to have more robust features and documentation):
map = new mapboxgl.Map({
container: 'map', // container id
style: videoStyle,
center: [-73.945360, 40.717533], // starting position
bearing: 90,
zoom: mapInitZoom // starting zoom
});
However, now that I need to use leaflet in order to get the distance from the center point, all of the leaflet documentation instantiates maps like this:
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
Is there a way I can continue my project using the Mapbox GL JS API and leaflet combined? Can anyone direct me to an examples or parts of the API documentation where I can read about this?
Oh, and the reason I think I need leaflet is because I need to add image layers to my map like this reference diagram image:
You can add image to a mapbox-gl-js map. Here is an example on how to do this: https://www.mapbox.com/mapbox-gl-js/example/image-on-a-map/
As you can see in the example, you need to add an ImageSource:
map.addSource('overlay', {
type: 'image',
url: 'https://www.mapbox.com/images/foo.png',
coordinates: [
[-76.54, 39.18],
[-76.52, 39.18],
[-76.52, 39.17],
[-76.54, 39.17]
]
});
and then a Raster Layer based on this source:
map.addLayer({
'id': 'overlay',
'source': 'overlay',
'type': 'raster',
'paint': {'raster-opacity': 0.85}
});
Generally speaking Leaflet.js / mapbox.js is best suited for raster tile sets, while mapbox-gl-js is for vector tile sets.
If you want to use Leaflet with a vector tile set, you can have a look at some of the Leaflet plugins that support vector tile sets: https://github.com/mapbox/awesome-vector-tiles#clients

ArcGIS API - Cannot center or zoom

So, I am using the ARCGIS api in order to show some old maps, that should start center at and zoomed in to a certain city. After finally figuring out how to use the specific map I want as a basemap, I've struggled for a couple of hours trying to zoom and center at the right place. I am able to zoom in to this place using a default basemap (e.g. "streets"), but not using my custom basemap. I've tried both map.centerAndZoom and map.centerAt, but neither seem to work. The relevant code:
var map;
require(["esri/map", "esri/layers/ArcGISTiledMapServiceLayer", "dojo/on", "dojo/_base/json", "dojo/dom-style", "esri/request", "esri/geometry/Point", "esri/dijit/Search", "esri/dijit/LocateButton", "esri/tasks/GeometryService", "esri/tasks/locator", "esri/tasks/ProjectParameters", "esri/symbols/PictureMarkerSymbol", "dojo/domReady!"],
function(Map, ArcGISTiledMapServiceLayer) {
map = new Map("venster_Midden_2_Map");
var customBasemap = new ArcGISTiledMapServiceLayer(
"http://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_1815/MapServer");
map.addLayer(customBasemap);
map.centerAndZoom(51.1, 4.3, 0);
});
Does anyone have a clue on how to get the zoom and center working? Or might it be the case that certain maps simply don't allow such operations?
centerAndZoom is more intended for events, like when a user has chosen a certain city from a list and would like the map to automatically zoom to it. As richj points out, it also requires a point, and a zoom level of zero won't work.
If you don't want any of the Esri basemaps at all, just leave that out when initially creating the map. Slightly modifying this Tiled Map Service sample:
require(["esri/map", "esri/layers/ArcGISTiledMapServiceLayer", "dojo/domReady!"],
function(Map, Tiled) {
map = new Map("map", {zoom: 3});
var tiled = new Tiled("http://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_1815/MapServer");
map.addLayer(tiled);
}
);
Then, you will be able to include centerAndZoom as a response to an event (e.g. after the Tiled layer has been fully loaded from its web source).
require(["esri/map",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/geometry/Point",
"esri/SpatialReference",
"dojo/domReady!"],
function(Map, Tiled, Point, SpatRef) {
map = new Map("map", {zoom: 3});
var tiled = new Tiled("http://tiles.arcgis.com/tiles/nSZVuSZjHpEZZbRo/arcgis/rest/services/Historische_tijdreis_1815/MapServer");
map.addLayer(tiled);
var cityCenter = new Point(121000, 495000, new SpatRef({ wkid: 28992 }));
tiled.on("load",function(evt) {
map.centerAndZoom(cityCenter, 6);
});
});
Ref. Point constructor, centerAndZoom method, and Working with events.
From the relevant API documentation the centreAndZoom method takes a Point as its first argument. Also your zoom factor of zero looks like it might cause a problem.
You might have more luck with a Point and a non-zero zoom scale, like this:
map.centerAndZoom(new Point(51.1, 4.3), 0.5);
The method has a Deferred return type so that you can provide a callback to react when the method call has completed.
Maybe it is esri api bug, for me, it sometime (but not always) failed to move map center at lng, lat with zoom level 18
Here is how I work around:
Recommend:
map.centerAndZoom(new Point(lng, lat), 18);
Alternative: (sometimes, not always, it failed to move the map, maybe ESRI need to fix bug for Javascript api v3.24)
map.centerAt(new Point(lng, lat));
//or
// map.centerAt(new Point(lng, lat, new SpatialReference({wkid: 4326})));
map.setZoom(18);

Accessing Leaflet.js GeoJson features from outside

I want to interact with a leaflet powered map's GeoJson overlay (polygons) from outside of L.'s realm, but I don't seem to be able to access objects created by L..
Interaction would include:
getBounds(myFeature)
fitBounds(myFeature)
setStyle
etc
I can see Leaflet exposing L.GeoJSON.getFeature(), but I don't seem to be able to squeeze anything out of it. No documentation, and the inspector seems to suggest it does not take arguments... :\
Is this just there for future development?
You may use getLayer to get the feature by its id.
http://leafletjs.com/reference.html#layergroup-getlayer
var geojsonLayer = L.geoJson(data,{
onEachFeature: function(feature, layer) {
layer._leaflet_id = feature.id;
}});
geojsonLayer.addTo(map);
feature = geojsonLayer.getLayer(12345); //your feature id here
alert(feature.feature.id);

How to set zoomLevel in google Visualization Map api?

I am trying to implement visualization map api,following this link https://developers.google.com/chart/interactive/docs/gallery/map
i am successfully drawing the point on the google map but not able to set the zoomlevel.
For single point the zoomlevel automatic set to 19(max level).
my code:-
var map = new google.visualization.Map(document.getElementById('map_div'));
map.draw(data, {showTip: true, zoom:14, mapType: 'normal', useMapTypeControl:true, enableScrollWheel:false});
I have tried this map.setZoom(12) but its not working.
The name of the property that defines the zoom-level in google.visualization.Map is not zoom,
it's called zoomLevel (funny, the title of your question contains the correct answer^^)
However, it's curious that the visualization-API does not provide a method to access the underlying google.maps.Map-instance.
You may add such a method (on your own risk), add this to the onload-callback:
google.visualization.Map.prototype.getMap=function(){
for(var k in this){
if(this[k].constructor==google.maps.Map)return this[k];
}
}
you now may access the google.maps.Map-instance by calling the method getMap of the google.visualization.Map-instance.
Example:
map.getMap().setZoom(12);
That is because the map object has no setZoom method according to the documentation page that you have given.
You can probably try redrawing the map using using draw method like this
var newZoom = 12;
map.draw(data, {showTip: true, zoom:newZoom, mapType: 'normal', useMapTypeControl:true, enableScrollWheel:false});

How to reproject a vector layer when you switch between base maps of different projections

I have OpenLayers map with two base layers: MetaCarta (EPSG:4326) and Google map (Mercator). sphericalMercator = false, units are degrees. There are also some markers, boxes, and vector data on the map.
When I switch between the base layers (which are of different projections), the simple geometries (such as markers or boxes) are reprojecting automatically and displayed correctly. However vector layers (polylines) are just shifted, not reprojected. I think that I need to call some kind of "rebuild" function or add some parameter so that OpenLayers do this automatically when the base layer projection changes. But I have no idea how to do this.
I read about Spherical Mercator (http://docs.openlayers.org/library/spherical_mercator.html) and look through OpenLayers examples, but didn't find a solution.
The part of my code is below (all coordinates in vector.json is in degrees):
var metaCarta = new OpenLayers.Layer.WMS("MetaCarta",
"http://labs.metacarta.com/wms/vmap0?",
{layers: "basic"}
);
var gmap = new OpenLayers.Layer.Google(
"Google Streets",
{numZoomLevels: 40}
);
map.addLayers([metaCarta, gmap]);
map.setCenter(new OpenLayers.LonLat(139.8, 35.7), 11);
// Load vector data
var jsonFormat = new OpenLayers.Format.GeoJSON();
var vectorLayer = new OpenLayers.Layer.Vector("vector", {
style: {strokeColor: "gray",strokeWidth: 2}
});
OpenLayers.loadURL("vector.json", {}, null, function(response) {
var features = jsonFormat.read(response.responseText);
vectorLayer.addFeatures(features);
});
map.addLayer(vectorLayer);
You will need to define the projections and a suitable transform in OpenLayers. In turn, you will need to include the Proj4JS library (which is used by OpenLayers to perform these projection transformations)

Categories

Resources