add marker to middle of polyline in leaflet - javascript

I have a leaflet map with polyline data in. The polyline is styled how I want but what I would like is to have a marker at the centre of each line. Is this possible and if so what changes to the below do I need to make?
var pathstyling = {
stroke: true,
fillColor: "#b5b5b5",
color: "#b5b5b5",
weight: 5,
opacity: 1,
fillOpacity: 0.6,
dashArray: 10,
};
const path = L.geoJSON(path_line, {
style: pathstyling,
})
.bindPopup(function (layer) {
let cap_name = layer.feature.properties.name.replace(
/(^\w{1})|(\s+\w{1})/g,
(letter) => letter.toUpperCase()
);
return `<p>${cap_name}</p><a href="https://${layer.feature.properties.link}" target="_blank">View<a>`;
/******/
})
.addTo(map);

You can simply do this with leaflet core:
function calcMiddleLatLng(map, latlng1, latlng2) {
// calculate the middle coordinates between two markers
const p1 = map.project(latlng1);
const p2 = map.project(latlng2);
return map.unproject(p1._add(p2)._divideBy(2));
}
function createMiddleMarkers(line){
var latlngs = line.getLatLngs();
for(var i = 1; i < latlngs.length; i++){
var left = latlngs[i-1];
var right = latlngs[i];
var newLatLng = calcMiddleLatLng(map,left,right);
L.marker(newLatLng).addTo(map);
}
}
createMiddleMarkers(layer);
https://jsfiddle.net/falkedesign/g7e8w9tz/

Related

listening onclick on layerGroup Markers through map.on(click) - Leaflet.js

I have create a layergroup of markers. Now i want to listen/fire the onclick event through map.on("click"). i have tried the below code but it is not working.
I am able to do the similar with the polygon layers but getting no output with layer of markers.
please suggest me any way so that i can listen the click event on markers on map.
L1 = new L.LayerGroup();
for (let i = 0; i < data.length; i++) {
var marker = L.circleMarker([data[i].Lat, data[i].Long], 100)
.addTo(map)
.on("mouseover", function () {
this.setStyle({
fillColor: "green",
fillOpacity: 0.8,
});
})
.on("mouseout", function () {
this.setStyle({
fillColor: "blue",
fillOpacity: 0.2,
});
});
L1.addLayer(marker);
marker.on("click", function (e) {
ull = document.getElementById("this3");
ull.innerHTML = "";
var xx = document.getElementById("clickinfo");
xx.style.left = "0px";
var head = document.getElementById("heading3");
head.innerHTML = "Semi Info";
for (const key in data[i]) {
var element = document.createElement("li");
element.style.background = "#cce5ff";
element.style.margin = "5px 5px 5px 5px";
element.innerHTML = `${key}: ${data[i][key]}`;
ull.appendChild(element);
}
});
}
L1.addTo(map);
map.on("click", function (event) {
var latlng = event.latlng;
// L1.fireEvent("click", {
// latlng: latlng,
// layerPoint: event.layerPoint,
// containerPoint: event.containerPoint,
// originalEvent: event.originalEvent,
// layer: L1
// });
var layers = leafletPip.pointInLayer(latlng, L1);
layers.forEach(function (layer) {
L1.fireEvent("click", {
latlng: latlng,
layerPoint: event.layerPoint,
containerPoint: event.containerPoint,
originalEvent: event.originalEvent,
layer: layer,
});
});
// var layers= leafletPip.pointInMarker(latlng,L1);
// layers.forEach(function(layer){
// L1.fireEvent("click",{
// latlng: latlng,
// layerPoint: event.layerPoint,
// containerPoint: event.containerPoint,
// originalEvent: event.originalEvent,
// layer: layer
// });
// });
});

Show form in google maps in expanded mode on a webpage

I am trying to fix a bug in existing code.
I'm new to javascript and css.
The program was developed in .net vistual studio.
The problem is this: I have a page that has a map where I make a circle in a region of it. The behavior the system should have is when I click the circle button, the system should open a form with information from the region where I made the circle. However, when I expand the map, the form is hidden behind the map. Can anyone tell me how I can bring this form forward in the expanded map form? In the attached image, the window behind the map appears in blue.
click to see map image
function configPontosMapa(sender, args) {
var label, marker, dataItem, location, circle, coordenadas, polygon, tableView, lats,
lngs, idPonto, nome, barra, shape, idPtoGlobalAux;
var dataItems = $find(gridPontos).get_masterTableView().get_dataItems();
var latlngBounds = new google.maps.LatLngBounds();
mapa.ClearMap();
MapaLabel.ClearLabels();
clearMapaBotao();
clearMapaBotaoSubPonto();
for (var i = 0; i < dataItems.length; i++) {
dataItem = dataItems[i];
idPonto = dataItem.getDataKeyValue("IdPontoGeografico");
idPtoGlobalAux = dataItem.getDataKeyValue("IdPontoGlobal");
nome = dataItem.getDataKeyValue("Nome");
lats = dataItem.getDataKeyValue("LatitudesFormatadas").split('|');
lngs = dataItem.getDataKeyValue("LongitudesFormatadas").split('|');
if (lats.length == 1) {
location = new google.maps.LatLng(parseFloat(lats[0]), parseFloat(lngs[0]));
var raio = parseFloat(dataItem.getDataKeyValue("Raio"));
if (!raio) {
raio = 1;
}
circle = new google.maps.Circle({
center: location,
radius: raio,
strokeColor: corPadrao,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: corPadrao,
fillOpacity: 0.15,
map: mapa.Mapa,
entity: idPonto,
idPontoGlobal: idPtoGlobalAux,
zIndex: 0
});
if (idPtoGlobalAux) {
barra = new MapaBarraBotao(mapa.Mapa, circle.getCenter(), circle, showModalPontoGlobal);
}
else {
barra = new MapaBarraBotao(mapa.Mapa, circle.getCenter(), circle, showModalNovoPonto);
}
circle.barraBotao = barra;
shape = circle;
mapa.NewCircleByShape(circle);
latlngBounds.union(circle.getBounds());
marker = mapa.NewMarker();
marker.bindTo('position', circle, 'center');
marker.setOptions({ ponto: circle, title: nome });
marker.setIcon('../../../Images/Ponto/MarcadorPonto1.png');
//label.bindEvents(marker);
circle.setEditable(true);
circle.barraBotao.ocultaBotaoSalvarCancelar();
google.maps.event.addListener(circle, 'rightclick', function () {
novoSubponto(this);
});
google.maps.event.addListener(circle, 'center_changed', function () {
this.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.barraBotao.draw(this.getCenter());
});
google.maps.event.addListener(circle, 'radius_changed', function () {
this.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
});
} else {
coordenadas = [];
for (var j = 0; j < lats.length; j++) {
coordenadas[j] = Mapa.NewLatLng(parseFloat(lats[j]), parseFloat(lngs[j]));
}
latlngBounds.extend(coordenadas[0]);
polygon = mapa.NewPolygonByPaths(coordenadas);
polygon.setEditable(true);
polygon.getPath().obj = polygon;
if (idPtoGlobalAux) {
barra = new MapaBarraBotao(mapa.Mapa, polygon.getPath().getAt(0), polygon, showModalPontoGlobal);
}
else {
barra = new MapaBarraBotao(mapa.Mapa, polygon.getPath().getAt(0), polygon, showModalNovoPonto);
}
polygon.barraBotao = barra;
shape = polygon;
polygon.setOptions({
entity: idPonto,
idPontoGlobal: idPtoGlobalAux,
barraBotao: barra,
zIndex: 0
});
marker = mapa.NewMarkerAtPoint(coordenadas[0]);
marker.setOptions({ ponto: polygon, title: nome });
marker.setIcon('../../../Images/Ponto/MarcadorPonto1.png');
polygon.barraBotao.ocultaBotaoSalvarCancelar();
polygon.marker = marker;
google.maps.event.addListener(polygon.getPath(), 'set_at', function () {
var coord = this.getAt(0);
this.obj.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.obj.barraBotao.draw(coord);
this.obj.label.draw(coord);
this.obj.marker.setPosition(coord);
});
google.maps.event.addListener(polygon.getPath(), 'insert_at', function () {
this.obj.setOptions({ fillColor: corAlterado, strokeColor: corAlterado });
this.obj.barraBotao.draw(this.getAt(0));
});
google.maps.event.addListener(polygon, 'rightclick', function () {
novoSubPoligono(this);
});
}
google.maps.event.addListener(marker, 'click', function () {
mapa.Mapa.setCenter(this.getPosition());
mapa.Mapa.setZoom(15);
});
if (idPonto == 0) {
label = createLabel(dataItem.getDataKeyValue("Nome"), null, shape, showModalPontoGlobal);
}
else {
label = createLabel(dataItem.getDataKeyValue("Nome"), null, shape);
}
label.bindEvents(marker);
shape.label = label;
arrayBotao.push(barra);
}
mapa.SetBoundsCircle(latlngBounds);
}
If this form has position prop then you can add z-index to this element.
z-index: 10 should do.

Longitude and Latitude of polyline : Leaflet

Is their a way to get latitude and longitude of polyline?
var firstpolyline = new L.Polyline(pointList, {
color: 'black',
opacity: 5,
smoothFactor: 1,
weight: 3,
})
map.addLayer(firstpolyline);
firstpolyline.getLatLng();
here firstpolyline is givng an error that "getLatLng() is not a function". I want to check if polyline is within the map bound or not like this
var bounds = map.getBounds();
if(bounds.contains(firstpolyline.getLatLng())){
......
}
You have to use getLatLngs() function. So try this:
var firstpolyline = new L.Polyline(pointList, {
color: 'black',
opacity: 5,
smoothFactor: 1,
weight: 3,
})
map.addLayer(firstpolyline);
var arrayOfPoints = firstpolyline.getLatLngs();
Then you can easily iterate over an array of points and get latitude and logitude or check if point is in bounds of polygon.
for(var i=0; i < arrayOfPoints.length; i++) {
if(map.getBounds().contains(arrayOfPoints[i])) {
console.log('is in bounds');
};
}

Make Leafletmarkers searchable and blurr out the others

With help of the StackOverflow community I built a leaflet map with markers for blogdata and articledata. The blogdata represents the IDs and geoloations of newsrooms and the articledata are the locations from articles the newsrooms wrote. So there are several articles per newsroom and I connected those with polylines (see picture below).
What I'd like now to do is make that leaflet map searchable, not for cities or countries but for the newsrooms ID. And I'd like to manage blurring all the other markers and lines out and zooming to the searched blog and it's connected articles.
This is what I got so far:
function myFunction() {
var map = L.map('map').setView([51.101516, 10.313446], 6);
// improve experience on mobile
if (map.tap) map.tap.disable();
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ',
maxZoom: 16
}).addTo(map);
map._layersMinZoom=5;
var newsroomsById = {};
for(i=0; i<newsrooms.length; i++) {
newsroomsById[newsrooms[i].ID] = newsrooms[i];
}
for(i=0; i<articles.length; i++) {
// retrieve newsroom
var newsroom = newsroomsById[articles[i].ID];
// draw your polyline
var latlngs = [
[articles[i].lat, articles[i].long],
[newsroom.lat, newsroom.long]
];
var polyline = L.polyline(latlngs, {
color: 'grey',
weight: 2,
opacity: 0.5,
smoothFactor: 1,
}).addTo(map);
var room_marker = L.circleMarker([newsroom.lat, newsroom.long], {
radius: 3,
color: '#29D3A0',
fillColor: '#29D3A0',
fillOpacity: 1,
}).addTo(map);
room_marker.bindPopup("<strong style='color: #84b819'>Newsroom </strong>" + newsroom.ID + "<br>").openPopup();
var popup = L.popup();
var art_marker = L.circleMarker([articles[i].lat, articles[i].long], {
radius: 2,
color: '#000',
fillColor: '#000',
fillOpacity: 1,
}).addTo(map);
}
}
And this is how the map looks like (black is article, green is newsroom/blog)
EDIT:
To make the map searchable use the Leaflet plugin L.Search.Control
It's difficult to answer the search part of the question. I think you'll have to describe a use case for that.
However, once you have the ID of the newsroom you want to highlight, you can change the opacity of your polylines and circleMarkers using setOption
However, your code needs some adjustments: you need to keep an array of your markers and keep the ID of the newsrooms in the markers.
Another thing: you should not create newsroom markers in the article loop; it creates as many newsroom markers as your number of articles.
Here is a proposition (selection is made by clicking on the newsroom marker):
var selectedNewsroom = 0;
var newsroomsById = {};
// create newsroom markers
var newsroomMarkers = [];
for(i=0; i<newsrooms.length; i++) {
newsroomsById[newsrooms[i].ID] = newsrooms[i];
var room_marker = L.circleMarker([newsrooms[i].lat, newsrooms[i].long], {
radius: 20,
color: '#000',
opacity: .4,
fillOpacity: .4,
}).addTo(map);
//room_marker.bindPopup("<strong style='color: #84b819'>Newsroom </strong>" + newsrooms[i].ID + "<br>");
room_marker.ID = newsrooms[i].ID; // associate marker with newsroom
room_marker.on('click', function(e) {
console.log('clicked on ' + e.target.ID);
changeSelection(e.target.ID);
});
newsroomMarkers.push(room_marker); // keep marker reference for later
}
// create article markers and connections to newsrooms
var articleMarkers = [];
for(i=0; i<articles.length; i++) {
// retrieve newsroom
var newsroom = newsroomsById[articles[i].ID];
// draw your polyline
var latlngs = [
[articles[i].lat, articles[i].long],
[newsroom.lat, newsroom.long]
];
var polyline = L.polyline(latlngs, {
color: '#000',
weight: 1,
opacity: .4,
smoothFactor: 1,
}).addTo(map);
var art_marker = L.circleMarker([articles[i].lat, articles[i].long], {
radius: 2,
color: '#000',
fillColor: '#000',
opacity: .4,
fillOpacity: .4,
}).addTo(map);
art_marker.connection = polyline; // associate polyline with marker
art_marker.newsroomID = newsroom.ID;
articleMarkers.push(art_marker); // keep marker reference for later
}
// highlight or blur newsrooms base on which is selected
function changeSelection(newsroomID) {
// deselect everything
for(i=0; i<articleMarkers.length; i++) {
articleMarkers[i].setStyle({ opacity: .4, fillOpacity: .4 });
articleMarkers[i].connection.setStyle({ opacity: .4 });
}
for(i=0; i<newsroomMarkers.length; i++) {
newsroomMarkers[i].setStyle({ opacity: .4, fillOpacity: .4 });
}
if(selectedNewsroom == 0 || selectedNewsroom != newsroomID) {
selectedNewsroom = newsroomID;
for(i=0; i<articleMarkers.length; i++) {
if(articleMarkers[i].newsroomID == newsroomID) {
articleMarkers[i].setStyle({ opacity: 1, fillOpacity: 1 });
articleMarkers[i].connection.setStyle({ opacity: 1 });
}
}
for(i=0; i<newsroomMarkers.length; i++) {
if(newsroomMarkers[i].ID == newsroomID) {
newsroomMarkers[i].setStyle({ opacity: 1, fillOpacity: 1 });
}
}
}
else {
selectedNewsroom = 0;
}
}
And a working example.

Openlayer-3 : Draw a polyline with GPS coordinates

For my company, I must develop a function who draw a path with GPS coordinates. Indeed, my company use GPS to track runners during multiple race.
So, i tried many differents way to draw my polyline, my last version is:
_public.drawPolyline = function(pool, id, points, color, opacity, weight) {
try {
var l = points.length;
var latlngs = [];
var j=1;
for (var i = 0; i < l; i++) {
latlngs[i] = new ol.geom.Point(ol.proj.transform([points[i].longitude, points[i].latitude], 'EPSG:4326', 'EPSG:3857'));
};
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: color,
width: weight,
opacity: opacity,
radius: 6
})
});
//Check if pool exists, else create it
if (!_private._polyline.containsKey(pool)) {
_private._polyline.put(pool, new jQuery.Hashtable())
}
var currentPool = _private._polyline.get(pool);
//Check if line exists, if yes, update path
if (currentPool.containsKey(id)) {
var vectorLayer = currentPool.get(id).layer;
vectorLayer.setVisible(true);
} else {
var linefeature = new ol.source.Vector('Path', {styleMap: style});
var comp = new ol.geom.LineString(latlngs);
var featurecomp = new ol.Feature({
name: "Comp",
geometry: comp
});
var vector = new ol.layer.Vector({
title: pool,
visible: true,
source: linefeature
});
linefeature.addFeatures(featurecomp);
currentPool.put(id, linefeature);
currentPool.put(id, { "type": "Path", "url": id, "layer": vector });
var vectorLayer = currentPool.get(id).layer;
vectorLayer.setVisible(true);
}
} catch (e) {
console.log(e.message);
}
}
So, I wanted to draw a Polyline with a function with differents parameters:
- pool: an Hashtable storing my polyline
- id: not important
- points: Contain an array of objects (
{"location":[{"id":1854703,"latitude":42.831,"longitude":0.30087,"altitude":0,"hpl":0,"vpl":0,"speed":4,"direction":258,"date":"2012-08-25 03:43:23","device_id":786,"datereceived":"2012-08-25 03:43:23"}).
According to my test server, I have no error in my logs, but, I still don't have a polyline drawed.
If someone could help me with this, it would be great.
Regards, Brz.
You just need to create LineString points as below
points.push(ol.proj.transform([xx,yy],'EPSG:4326', 'EPSG:3857'));
Demo Link https://plnkr.co/edit/WqWoFzjQdPDRkAjeXOGn?p=preview
Edits
var vectorSource = new ol.source.Vector({});
var vectorSourcePoint = new ol.source.Vector({});
var style = new ol.style.Style({
image: new ol.style.Circle({
radius: 4,
fill: new ol.style.Fill({
color: color
}),
stroke: new ol.style.Stroke({
color: color,
width: weight,
opacity: opacity
})
})
});
var l = points.length;
var latlngs = [];
for (var i = 0; i < l; i++) {
latlngs.push(ol.proj.transform([points[i].longitude, points[i].latitude],'EPSG:4326', 'EPSG:3857'));
//below 3 lines of code creates point geometry. I think you don't need this
var point = new ol.geom.Point([points[i].longitude, points[i].latitude]).transform('EPSG:4326', 'EPSG:3857');
var fea = new ol.Feature({geometry:point});
vectorSourcePoint.addFeature(fea);
};
//below lines of code creates polyline. You are missing these lines.
var thing = new ol.geom.MultiLineString([points]);
var featurething = new ol.Feature({
name: "Thing",
geometry: thing
});
vectorSource.addFeature( featurething );

Categories

Resources