Draw the polyline along the path of the map in openlayer3 - service

I following code how to draw the polyline along path of the map, know for the point present in the map will just give the straight line how to get along the path of the lanes
<!DOCTYPE html>
<html>
<head>
<title>Rotation example</title>
</head>
<body>
<div style="width:80%; height:80%; position:fixed; border: 1px solid;" id="map"></div>
<script src="http://openlayers.org/en/v3.11.2/build/ol.js"></script>
<script>
var lineString = new ol.geom.LineString([
[103.986083, 1.350349],
[103.985097, 1.349067]
]);
lineString.transform('EPSG:4326', 'EPSG:3857');
var lineLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [new ol.Feature({
geometry: lineString,
name: 'Line'
})]
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: [255, 255, 0, 0.5],
width: 10
})
})
});
var view = new ol.View({
center: ol.proj.transform([103.986908, 1.353199], 'EPSG:4326','EPSG:3857'),
zoom: 18,
rotation: 68*Math.PI/180
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
lineLayer
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: view
});
</script>
</body>
</html>
Is there any direction service provided by openlayer3 please point to sample to accomplish it

If you have coordinates along the lanes you can use MultiLineString instead of LineString.

You need to use a routing service for such action. You may setup your own service or you may use any online available. here you can find a list of free online routers and decide which one best feet to your needs.
Once you get your root polyline out of the selected service you can then decode (if encoded) and draw your line within your ol3 map.
Also cosider, depending on the service you are going to use, that ol3 offers a class for reading and writing data in the Encoded Polyline Algorithm Format which is described here

Related

How to add I3SLoader 3dtile layer (deck.gl) integrated with mapbox

I am trying to add arcgis 3d layer in mapbox with DeckGL. But I have this error (Uncaught TypeError: Tile3DLayer is not a constructor)
If I could bring data from arcgis sceneserver ,I try add two maps like compare(mapbox gl swipe tool) them.
maybe there are different ways to solve this problem. Taking the arcgis data I need and calling two maps on the same web page. Then make a presentation with the comparison tool between these maps.
<html>
<head>
<title>deck.gl + Mapbox Integration</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src="https://unpkg.com/deck.gl#^6.2.0/deckgl.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js"></script>
<link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css">
<script src="https://unpkg.com/#loaders.gl/i3s#2.1.6/dist/dist.min.js"></script>
</head>
<body>
<div id="map" style="width: 100vw; height: 100vh"></div>
</body>
<script type="text/javascript">
const { MapboxLayer, ScatterplotLayer } = deck;
// Get a mapbox API access token
mapboxgl.accessToken = 'pk.eyJ1IjoidWJlcmRhdGEiLCJhIjoiY2pudzRtaWloMDAzcTN2bzN1aXdxZHB5bSJ9.2bkj3IiRC8wj3jLThvDGdA';
// Initialize mapbox map
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [-74.50, 40],
zoom: 9
});
const {DeckGL, Tile3DLayer} = deck;
const {I3SLoader} = loaders;
const deckgl = new DeckGL({
controller: true,
layers: [
new Tile3DLayer({
id: 'tile-3d-layer',
data:
'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_Bldgs/SceneServer/layers/0',
loader: I3SLoader,
onTilesetLoad: (tileset) => {
const {zoom, cartographicCenter} = tileset;
const [longitude, latitude] = cartographicCenter;
const viewState = {
...deckgl.viewState,
zoom: zoom + 2.5,
longitude,
latitude
};
deckgl.setProps({initialViewState: viewState});
}
})
]
});
map.on('load', () => {
map.addLayer(deckgl);
});
</script>
</html>
I'm using React, the core code is here, hope I can help you.
// import { MapboxLayer } from '#deck.gl/mapbox';
// import {I3SLoader} from '#loaders.gl/i3s';
// import { Tile3DLayer } from '#deck.gl/geo-layers';
// import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = 'your-token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-122.51473530281777,37.70463582140094],
zoom: 13
});
const layer = new MapboxLayer({
id:'i3s',
type: Tile3DLayer,
data: 'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_Bldgs/SceneServer/layers/0',
loader: I3SLoader
});
map.on('load', () => {
map.resize();
map.addLayer(layer);
});

Fixing "Can't find variable: mapboxgl" Issue

I am not good a JS at all but after following the examples from the MAPBOX website I am unable to render a map at all. Code is exactly as it should be according to the website. The only error that shows up Can't find variable: mapboxgl. After researching this I have not found anything on this. What am I doing wrong?
MyCode:
<script>
mapboxgl.accessToken = '<? print $mapboxapi; ?>';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
center: [<? print $SQL["long"] ?>, <? print $SQL["lat"] ?>], // starting position [lng, lat]
zoom: 9 // starting zoom
});
var marker = new mapboxgl.Marker()
.setLngLat([<? print $SQL["long"] ?>, <? print $SQL["lat"] ?>])
.addTo(map);
</script>
This renders out this code:
<script>
mapboxgl.accessToken = 'xxxxxxxxxxxxxxxxxxxxxxxx';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
center: [-00.00000, 00.000000000], // starting position [lng, lat]
zoom: 9 // starting zoom
});
var marker = new mapboxgl.Marker()
.setLngLat([-00.00000, 00.000000000])
.addTo(map);
</script>
You probably haven't included the necessary script and CSS files in your <head> section. These bits:
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />

Leaflet routing machine not giving the optimal route (by far)

I have issues when trying to show a route on my leaflet map:
L.Routing.control({
router: L.Routing.mapbox(''),
profile:"mapbox/driving",
addWaypoints:false,
waypointMode:'snap',
routeWhileDragging: true,
show:false,
fitSelectedRoutes:false,
plan:false,
draggableWaypoints:false,
lineOptions:{
styles:[ {color: 'black', opacity: 0.8, weight: 6}, {color: 'red', opacity: 1, weight: 2}]
},
waypoints: [
L.Routing.waypoint(L.latLng(28.6114741,77.2112497),"New Dehli"),
L.Routing.waypoint(L.latLng(30.7304186,76.7789926),"Chandigarh"),
L.Routing.waypoint(L.latLng(31.1047637,77.1717752),"Shimla"),
L.Routing.waypoint(L.latLng(31.4493988,77.629702),"Rampur"),
L.Routing.waypoint(L.latLng(31.9755409,78.5961753),"Changoa"),
L.Routing.waypoint(L.latLng(32.2251899,78.0610693),"Kaza"),
L.Routing.waypoint(L.latLng(32.4513357,77.860656),"Hanse"),
L.Routing.waypoint(L.latLng(32.4386919,77.7497997),"losar gompa"),
],
}).addTo(map);
At the 7th waypoint (Hanse), the route is doing a U turn, adding a thousand kms to reach the 8th point that is only a few kms away.
What's going on here? I can't figure it out. Any help is welcome!
Welcome to SO!
This is reproducible with OSMR service instead of Mapbox:
var map = L.map("map").setView([32.4513357, 77.860656], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
L.Routing.control({
//router: L.Routing.mapbox(''),
//profile: "mapbox/driving",
addWaypoints: false,
waypointMode: 'snap',
routeWhileDragging: true,
show: false,
fitSelectedRoutes: false,
plan: false,
draggableWaypoints: false,
lineOptions: {
styles: [{
color: 'black',
opacity: 0.8,
weight: 6
}, {
color: 'red',
opacity: 1,
weight: 2
}]
},
waypoints: [
/*L.Routing.waypoint(L.latLng(28.6114741, 77.2112497), "New Dehli"),
L.Routing.waypoint(L.latLng(30.7304186, 76.7789926), "Chandigarh"),
L.Routing.waypoint(L.latLng(31.1047637, 77.1717752), "Shimla"),
L.Routing.waypoint(L.latLng(31.4493988, 77.629702), "Rampur"),
L.Routing.waypoint(L.latLng(31.9755409, 78.5961753), "Changoa"),
L.Routing.waypoint(L.latLng(32.2251899, 78.0610693), "Kaza"),*/
L.Routing.waypoint(L.latLng(32.4513357, 77.860656), "Hanse"),
L.Routing.waypoint(L.latLng(32.4386919, 77.7497997), "losar gompa"),
],
}).addTo(map);
#map {
height: 200px;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css">
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet-src.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine#3.2.7/dist/leaflet-routing-machine.css">
<script src="https://unpkg.com/leaflet-routing-machine#3.2.7/dist/leaflet-routing-machine.js"></script>
<div id="map"></div>
It looks like the OSM database thinks there is a "barrier" obstacle near your arrival point ("losar gompa"):
If this obstacle type cannot be crossed by car, that would explain why the router takes another (very long…) route instead.
If you think this obstacle no longer exists, please feel free to create an account on OpenStreetMap and edit the map! There is a very high chance that Mapbox router uses OSM data, therefore your modifications would be reflected some time later in Mapbox.

MapBox markers Move on zooming

I'm working on MapBoxgl and I want to add several markers.
Here is my index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href=" /assets/css/bootstrap.min.css " rel="stylesheet" />
<link href=" /assets/css/mapbox-gl.css " rel="stylesheet" />
<link href=" /assets/css/main.css " rel="stylesheet" />
</head>
<body>
<div id="map"></div>
<script src="/assets/js/mapbox-gl.js"></script>
<script src="/assets/js/map-style.js"></script>
</body>
</html>
This is map-style.js:
var map = new mapboxgl.Map({
container: 'map',
center: [57.3221, 33.5928],
zoom: 5,
style: style
});
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [30.61, 46.28]
},
properties: {
title: 'point 1',
description: 'point 1 Description',
message: 'point1',
iconSize: [25, 25]
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [30.62, 46.2845]
},
properties: {
title: 'point 2',
description: 'point 2 Description',
message: 'point 2',
iconSize: [25, 25]
}
}]
};
map.on('load', function () {
// add markers to map
geojson.features.forEach(function(marker) {
// create a DOM element for the marker
var el = document.createElement('div');
el.className = 'markers';
el.style.backgroundImage = 'url(assets/marker-azure.png)';
//el.style.width = marker.properties.iconSize[0] + 'px';
el.style.height = marker.properties.iconSize[1] + 'px';
el.addEventListener('click', function() {
window.alert(marker.properties.message);
});
// add marker to map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);
});
});
And following is main.css portion related to map and marker:
#map { position:absolute; top:0; bottom:0; width:100% }
.markers {
display: absolute;
border: none;
border-radius: 50%;
cursor: pointer;
padding: 0;
}
So, my problem is that when I add width property to markers, their icon be displayed correctly (with a bit stretch) but they are in wrong coordinate and move on zoom, like picture below:
On the other hand, if width property is eliminated, they are in right place and does not move on zooming, but they are very stretched and in fact as wide as screen (following image):
It's noteworthy that I've used bootstrap. Can it be the reason of this? If not, what's the problem?
Thanks
import 'mapbox-gl/dist/mapbox-gl.css';
Adding import css works for me.
I found the solution and share it here with others who will encounter this problem. The problem caused because of using a not-most-recent version of the library. After upgrading to the latest release, I could get rid of that problem.
Note that these kinds of problems sometimes occur, when you use npm. Make sure that the library is downloaded completely and It's the latest release.
Latest releases of MapBox can be found at here.
had similar issue, the marker seemed to change position on zoom in/out, fixed it by setting offset, thought to share if it can help others, here is the fiddle
// add marker to map
var m = new mapboxgl.Marker(el, {offset: [0, -50/2]});
m.setLngLat(coordinates);
m.addTo(map);
(Using mapbox 1.13.0)
I had a similar issue where the popups weren't displaying and would change position based on zoom.
Mapbox officially states that you need to include the css file to have markers and popups work as expected.
https://docs.mapbox.com/mapbox-gl-js/guides/install/
HOWEVER, you can also copy that css directly into a component and use that as an element. For example:
export default function MarkerMapTest(props) {
const mapContainer = React.useRef(null)
const map = React.useRef(null)
const elemRef = React.useRef(null)
React.useEffect(() => {
map.current = new mapboxgl.Map({
container: mapContainer.current,
style: "mapbox://styles/mapbox/dark-v10",
center: [151.242, -33.9132],
zoom: 14,
})
const marker = new mapboxgl.Marker({
element: elemRef.current,
})
.setLngLat([151.242, -33.9132])
.addTo(map.current)
}, [])
return (
<div
style={{ width: 600, height: 600, backgroundColor: "gray" }}
ref={mapContainer}
>
<div
style={{
width: 30,
height: 30,
borderRadius: 15,
backgroundColor: "red",
position: "absolute", // !
top: 0, // !
left: 0, // !
}}
ref={elemRef}
/>
</div>
In my case the svg I used had some space around the real content. That way it seemed for me that the marker was moving. A simple fix was to remove the space around the content (e.g. with the "Resize page to drawing or selection" option of inkscape: https://graphicdesign.stackexchange.com/a/21638)
Also it is important to set display: block on the svg-marker. See: https://stackoverflow.com/a/39716426/11603006

OSM leafleft JS Getting the center and radius of an editable circle

I am using OSM using layer Leaflet Js.I am trying to edit the circle using the Leaflet.Editable.js. I think, getting the circle and the radius using the 'editable:vertex:dragend' event is not a right approach.
Is there any other way to get the circle center and radius after dragging it.
Here is my apprach
<link href="https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/master/leaflet.css" rel="stylesheet" type="text/css" />
<script src="https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/master/leaflet.js"></script>
<script src="Leaflet.Editable.js"></script>
<style type="text/css">
#mapdiv { height: 500px; }
</style>
<div id="mapdiv"></div>
<script type="text/javascript">
var map = L.map('mapdiv', {editable: true}).setView([23.2599333, 77.41261499999996], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 30
}).addTo(map);
L.EditControl = L.Control.extend({
options: {
position: 'topleft',
callback: null,
kind: '',
html: ''
},
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
link = L.DomUtil.create('a', '', container);
link.href = '#';
link.title = 'Create a new ' + this.options.kind;
link.innerHTML = this.options.html;
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', function () {
window.LAYER = this.options.callback.call(map.editTools);
}, this);
return container;
}
});
var circle = L.circle([23.2599333, 77.41261499999996], {radius: 1000}).addTo(map);
circle.enableEdit();
circle.on('dblclick', L.DomEvent.stop).on('dblclick', circle.toggleEdit);
//circle.on('editable:vertex:drag', function (e) {
map.on('editable:vertex:dragend', function (e) {
//alert(e.vertex.latlng);
circle.setLatLng(e.vertex.latlng);
alert(circle.getRadius());
});
</script>
Any help on this regard or the best approach will be really helpful.
Yes, I would suggest using
map.on('editable:drawing:move', function (e) {
console.log(circle.getLatLng())
console.log(circle.getRadius());
});
This works for either dragging the vertex on the outer edge of the circle, or drags of the entire circle from the center marker.