Adding a Shapes files as a Layer on Mapbox Map - javascript

I have a shapes file from here. I wish to add it on a Map, similar to what is done on the web page. I am not quite sure how to proceed with it. I want to use it on Web and hence use JavaScript.
Someone suggested me to use the shapes file as a Layer on the map. But how to go about it? Anyone experience with Mapbox, Leaflet or OSM please guide.

I was finally able to add the shapes file by uploading it as a tileset to Mapbox Studio.
It provided me with a map Id and source-layer name which I was able to add as a Layer on my Mapbox map as follows:
map.addLayer({
id: '<id>',
type: 'fill',
source: {
type: 'vector',
url: 'mapbox://<map-id>' // Mapbox tileset Map ID
},
'source-layer': '<layer-name>', // name of tilesets
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8,
'fill-outline-color': '#000'
}
});

In order to load a SHP file and display it on a Leaflet / Mapbox.js map, you have several Leaflet plugins that can make the task easy.
For example leaflet.shapefile (online demo where you can drop your zipped SHP and DBF files).
The data source that you mention also provides KML format, which may be easier to use.
For KML, you can use for example leaflet-omnivore:
universal format parser for Leaflet & Mapbox.js
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38, -102.0], 5);
omnivore.kml('a.kml').addTo(map);
Live example with Leaflet and leaflet-omnivore: https://plnkr.co/edit/KVXqBScBuIrAahg4VsGi?p=preview

Related

Mapbox-gl Hosted S3 - addsource

I am working on this project where I want to add relatively dynamic data (updating every 15minutes) to a mapbox-gl via a serverless solution. I followed this excellent guide on creating serverless vector tiles and have the base tiles working.
My question is now how would you achieve adding a geojson point layer to the map (hosted on a simple HTML page), using something like:
var map = new mapboxgl.Map({
container: 'map',
style: style: "https://{domain}/bright.json",
});
var url = 'https://{domain}/geojsonfile.json'
map.addSource('geojsonfile', {
'type': 'geojson',
'data': url
});
map.addLayer({
'id': 'geojsonfile',
'type': 'symbol',
'source': 'geojsonfile',
'layout': {
'icon-image': 'rocket-15'
}
});
In a serverless vector environment without using Tippecanoe to convert the json file into protobuf vector tiles and instead adding the layer direct to the map from the javascript file. The above js for addsource and addlayer come from this Mapbox guide.
I can get the above js working when I pass in a mapboxgl.accessToken instead of self-hosting; however that's as far as I have been able to get. The geojson file is hosted in a CORS enabled s3 bucket.
Is the issue with loading in the source or displaying the layer? I have also tried modifying the bright.json file to handle the source and layer so that I only have to replace the s3 file, however have had no luck.
Any and all help / suggestions are much appreciated.
After quite a lot of blind trial and error, finally figured out a solution. Turns out my original script was trying to load the layer to the map on-load. However, the tile base load is configured via the style and tile files pre-load.
Therefore, the js addSource needs to be added to the map post-load and then style on-load.
this.map.on('style.load', function () {
this.pastInitialLoad = true;
this.map.addSource("geojsonfile", {
"type": "geojson",
"data": url }
);
If anyone else is stuck, these guides / sources were of great help!
https://schwanksta.com/blog/vector-tiles-introduction-pt1
http://fuzzytolerance.info/blog/2016/03/16/Leaflet-to-Mapbox-GL/
https://github.com/mapbox/mapbox-gl-js/issues/2268

How to display ESRI Vector base map in Openlayers 3

I am trying to add the new ESRI Vector Basemaps in OpenLayers 3. I have gotten so far as to display the layer un-styled by modifying the Mapbox Example published by OpenLayers.
Clearly I had to remove the style: createMapboxStreetsV6Style() option to get the esri layer to display. So basically the map does not know the style information to display the layer correctly.
I think it should be possible to do it because ESRI's Leaflet port and example is doing this already. I think information on esri's style IDs is available in here Leaflet code.
OpenLayers should already be able to use all this information as it is able to display Mapbox Layer. What I need help with is, how to make it use ESRI's style information.
Here's what I have so far (codepen here):
var map = new ol.Map({
layers: [
new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
tilePixelRatio: 16,
url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf'
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
.map {
background: #f8f4f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
There is a separate library, https://npmjs.com/package/ol-mapbox-style, which makes it easy to consume vector tile maps including their styles in OpenLayers. It reads the style doc and builds the whole map from it. For one of the ESRI maps you linked above, the code to get that map in OpenLayers would be
var map = new ol.Map({
target: 'map'
});
olms.apply(map, 'https://www.arcgis.com/sharing/rest/content/items/4f4843d99c34436f82920932317893ae/resources/styles/root.json?f=json');
You can replace 4f4843d99c34436f82920932317893ae with one of the other map ids listed in the Leaflet example to get the other maps.
You can also play with that code - I have created a CodePen: https://codepen.io/ahocevar/pen/xLaBVV.
#ahocevar's suggest is perfect,
esri's root.json, sprite and glyphs are not full URL, the are only last part as see below
In your example, those not full URL works, but, I have test it in mapbox js api, it failed, error is can't parse URL,
I have to change those url to a full URL, to make it works.
root_json = {
"version" : 8,
"name": "test",
//"sprite" : original_rootJson.sprite, // original is not a full URL, not work "../sprites/sprite"
// "sprite" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/sprites/sprite",
"sprite" : _sprite,
// "glyphs" : original_rootJson.glyphs, // original is not a full URL, not work "../fonts/{fontstack}/{range}.pbf"
// "glyphs" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
"glyphs" : _glyphs,
// root json specification : https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/
"sources" : {
"esri" : {
"type" : "vector",
// By supplying TileJSON properties such as "tiles", "minzoom", and "maxzoom" directly in the source:
"tiles": [
// "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/tile/{z}/{y}/{x}.pbf"
_tile_pbf
],
// "maxzoom": 14
// By providing a "url" to a TileJSON resource
// not work,yet
// "url" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Esri_Childrens_Map/VectorTileServer/tile/{z}/{y}/{x}.pbf"
// "url": "http://api.example.com/tilejson.json"
}
},
"layers": original_rootJson.layers
} // root_json

loading GeoJSON markers into MapBox

I'm trying to figure out how to load GeoJSON list on lon/lat coordinates into a MapBox map. I think I'm close, I just can't seem to get it actually working.
I have a demo page set up here: http://sandbox.charliehield.com/mapbox/
Here's the GeoJSON file:
{
"type": "MultiPoint",
"coordinates": [
[
"-105.277803",
"40.006977"
],
[
"-93.304988",
"44.947198"
],
[
"151.206990",
"-33.867487"
]
]
}
The HTML is simply:
<div id="map"></div>
And the JS:
var map = mapbox.map('map');
map.addLayer(mapbox.layer().id('examples.map-zr0njcqy'));
map.ui.zoomer.add();
// example.geojson is a well-formed GeoJSON document. For this
// style, the file must be on the same domain name as the map,
// or loading will not work due to cross-domain request restrictions
var markers = mapbox.markers.layer().url('markers.geojson');
mapbox.markers.interaction(markers);
map.addLayer(markers);
// Zoom and center the map
map.zoom(2).center({ lat: 39.74739, lon: -105 });
Looks like you need to format your geojson a little more explicitly with a geometry object and key value pairings. See http://mapbox.com/mapbox.js/example/custom-marker-tooltip as an example.
I had the same issue loading geojson to my mapbox map. The comments in the JS actually pointed out the reason: there are cross-domain request restrictions.
You could check the same origin policy and you would want to run the application somewhere else.

OpenLayers Map BoundingBox calculation

I'm using the GeoServer to hold some maps, and just a simple OpenLayers app to load and show the data (for now).
I'm successfully loading the demo data (which is in WGS84), but when it comes to my data (which is in Balkans Zone 7, EPSG:31277), when I look at the request, it seems like the BBOX is completely out of order.
I checked the BBOX from the GeoServer preview page (which is made with openLayers) and it looks like this, and works:
http://127.0.0.1:2113/geoserver/GISHome/wms?LAYERS=GISHome%3ANis11Katastar&STYLES=&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A31277&BBOX=7572000,4796000,7574000,4798000&WIDTH=512&HEIGHT=512
The only thing that's different with my request is the BBOX. When copying the BBOX into my request, it works.
http://127.0.0.1:2113/geoserver/wms?LAYERS=Nis11Katastar&FORMAT=image%2Fpng&WIDTH=256&HEIGHT=256&PROJECTION=EPSG%3A31277&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180,-90,0,90
In the GeoServer source, the bounds are somehow calculated and hardcoded. The question is, how? Is there a way not to hardcode them? How should I calculate them. I've tried adding bounds, maxExtent, resolution, I'm obviously missing something more than that here. The GeoServer works fine, I'm using the layers from QuantumGIS.
Ext.onReady(function() {
var map = new OpenLayers.Map();
var layer = new OpenLayers.Layer.WMS(
"Global Imagery",
"http://127.0.0.1:2113/geoserver/wms",
{
LAYERS:'Nis11Katastar',
format: 'image/png',
width:600,
height:400,
projection: new OpenLayers.Projection("EPSG:31277"),
}
);
Thankyou.
Oh, yes, I'm using GeoExt, but that doesn't change much.
It seems solved. I was setting the right properties, but to the WMS layer object, not to the map object. As for the bounds question, I'm just copying the bounds from the geoserver control panel.

Why does an Esri Extent load for one map layer but not for another? ArcGIS Javascript API

I am having the weirdest problem right now using the ArcGIS Javascript API (v2.4). I'm merely trying to create an instance of an ESRI topo map with an extent, and then add a layer.
Here is the code that works. I create an extent, then a map, then a streetmap layer and then finally add that layer.
var startExtent = new esri.geometry.Extent(-71.5, 42, -71, 42.5, new esri.SpatialReference({wkid:4326}) );
map = new esri.Map("map_canvas", { extent: startExtent,fitExtent:false });
var streetmap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer");
map.addLayer(streetmap);
However when I try and do the same thing with a separate server, it doesn't work.
var startExtent = new esri.geometry.Extent(-71.5, 42, -71, 42.5, new esri.SpatialReference({wkid:4326}) );
map = new esri.Map("map_canvas", { extent: startExtent,fitExtent:false });
var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer");
map.addLayer(basemap);
I know that the faulty-layer's server works, because if I create a map with no extent, it shows the full world imagery server, so it appears that creating a map in with one layer and an extent works, while creating a map with a different layer but the same extent does not work.
Any ideas why?
In your second example, the layer is in web Mercator.
Try converting the extent from geographic to web Mercator before using it in the map constructor.
The easiest way to convert the extent is to use esri..geometry.geographicToWebMercator.

Categories

Resources