Add Markers from Object Array - javascript

Pardon me if this question is silly. I've got an array in an object that I need to add to a map. I know it needs a for loop (likely in the object) to access the additional properties in the array. Only the last indexed value is shown on the map when I execute the code. Thanks in advance for your help.
var map = L.map('map', {
center: [29.940125, -90.08346],
zoom: 13
});
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
maxZoom: 18,
attribution: '© OpenStreetMap'
};
// requests some map tiles
var tiles = L.tileLayer(basemap_url, basemap_attributes);
map.addLayer(tiles);
var i = 0
// declare hotspots object
var hotspots = [{
name: "Mariza",
properties: {
description: "Italian-inspired fare dished out in an airy loft building with an industrial-chic vibe.",
coordinates: [29.9629337, -90.0501008],
url: 'http://marizaneworleans.com/',
phone: '(504) 598-5700',
icon: 'svgs/restaurant-15.svg'
},
name: "Tipitina's",
properties: {
description: "Founded as a clubhouse for Professor Longhair, Tip's has played host to NOLA music legends since opening its doors in 1977.",
coordinates: [29.917284, -90.042986],
url: 'https://www.tipitinas.com//',
phone: '(504) 895-8477',
icon: 'svgs/music-15.svg'
},
name: "Euclid Records New Orleans",
properties: {
description: "We’re 4000 square feet of boss vinyl both new and used.",
coordinates: [29.962066, -90.042970],
url: 'https://euclidnola.com/',
phone: '(504) 947-4348',
icon: 'svgs/music-11.svg'
}
}];
// declare variable for accessing object properties
var props = hotspots[i].properties;
var icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
var popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
var marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
marker.on("mouseover", function () {
this.openPopup();
});
marker.on("mouseout", function () {
this.closePopup();
});

You need a for loop in order to iterate over all the hotspots and add them to the map:
var map = L.map('map', {
center: [29.940125, -90.08346],
zoom: 13
});
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
maxZoom: 18,
attribution: '© OpenStreetMap'
};
// requests some map tiles
var tiles = L.tileLayer(basemap_url, basemap_attributes);
map.addLayer(tiles);
// declare hotspots object
var hotspots = [{
name: "Mariza",
properties: {
description: "Italian-inspired fare dished out in an airy loft building with an industrial-chic vibe.",
coordinates: [29.9629337, -90.0501008],
url: 'http://marizaneworleans.com/',
phone: '(504) 598-5700',
icon: 'svgs/restaurant-15.svg'
},
name: "Tipitina's",
properties: {
description: "Founded as a clubhouse for Professor Longhair, Tip's has played host to NOLA music legends since opening its doors in 1977.",
coordinates: [29.917284, -90.042986],
url: 'https://www.tipitinas.com//',
phone: '(504) 895-8477',
icon: 'svgs/music-15.svg'
},
name: "Euclid Records New Orleans",
properties: {
description: "We’re 4000 square feet of boss vinyl both new and used.",
coordinates: [29.962066, -90.042970],
url: 'https://euclidnola.com/',
phone: '(504) 947-4348',
icon: 'svgs/music-11.svg'
}
}];
//// LOOP GOES HERE: ////
for ( let i = 0; i < hotspots.length; i++ ){
// declare variable for accessing object properties
let props = hotspots[i].properties;
let icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
let popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
let marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
marker.on("mouseover", function() {
this.openPopup();
});
marker.on("mouseout", function() {
this.closePopup();
});
}

There isn't a loop anywhere, so i is always going to be 0
Put it in a for-loop?
for(var i = 0; i < hotspots.length; i++) {
var props = hotspots[i].properties;
var icon = L.icon({
iconUrl: props.icon,
iconSize: [40, 40],
popupAnchor: [0, -22],
className: "icon"
});
var popup = `<h3>${hotspots[i].name}</h3>
<p>${props.description}</p>
<p><b>website</b>: <a href='${props.url}'>${props.url}</a></p>
<p><b>phone</b>: ${props.phone}</p>`
var marker = L.marker(hotspots[i].properties.coordinates, {
icon: icon
})
.addTo(map)
.bindPopup(popup);
}

Related

Creating an event on a map maker

//Final Code
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
// -- GeoJSON layer --
// Define a GeoJSON source that will load features via a http call. By
// specifying the projection of the map's view OL3 will transform the coordinates
// for display
var planningAppsSource = new ol.source.GeoJSON({
'projection': map.getView().getProjection(),
'url': 'http://localhost/osgis-ol3-leaflet-master/ol3/data.geojson'
});
// Create a vector layer to display the features within the GeoJSON source and
// applies a simple icon style to all features
var planningAppsLayer = new ol.layer.Vector({
source: planningAppsSource,
style: new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 40],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'marker-icon.png'
}))
})
});
// Add the layer to the map
map.addLayer(planningAppsLayer);
var input = document.getElementById('input-airports');
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(
evt.pixel, function(ft, l) { return ft; });
if (feature) {
console.log(feature.getProperties());
input.value = feature.get('desc');
}
});
map.on('pointermove', function(e) {
if (e.dragging) return;
var hit = map.hasFeatureAtPixel(map.getEventPixel(e.originalEvent));
});
I succeed creating a simple map with OL3 with static markers pointing airports which take them data in an external JSON file.
But now i would like that when i click on a marker, create a function which find the name of the airport corresponding to the marker, in my JSON file and show it in an external field type:input.
I already tried to create a click event on my marker, an open layers interaction, try to take back some data in my Json File. but it seems like i'm missing something, all my little parts doesn't fit all together.
I don't know where i can start :s
Thank you all for your answers.
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
// -- GeoJSON layer --
// Define a GeoJSON source that will load features via a http call. By
// specifying the projection of the map's view OL3 will transform the coordinates
// for display
var planningAppsSource = new ol.source.GeoJSON({
'projection': map.getView().getProjection(),
'url': 'http://localhost/osgis-ol3-leaflet-master/ol3/data.geojson'
});
// Create a vector layer to display the features within the GeoJSON source and
// applies a simple icon style to all features
var planningAppsLayer = new ol.layer.Vector({
source: planningAppsSource,
style: new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 40],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'marker-icon.png'
}))
})
});
// Add the layer to the map
map.addLayer(planningAppsLayer);
// Map Click event
planningAppsSource.addEventListener(map, 'click', function(event){
var getHttpRequest = function () {
var httpRequest = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType) {
httpRequest.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
if (!httpRequest) {
alert('Abandon :( Impossible de créer une instance XMLHTTP');
return false;
}
return httpRequest
}
});
GeoJSON:
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-145.494,
-17.3595
]
},
"type": "Feature",
"properties": {
"code": "AAA",
"lon": "-17.3595",
"lat": "-145.494",
"name": "Anaa Airport",
"city": "Anaa",
"state": "Tuamotu-Gambier",
"country": "French Polynesia",
"woeid": "12512819",
"tz": "Pacific\/Midway",
"phone": "",
"type": "Airports",
"email": "",
"url": "",
"runway_length": "4921",
"elev": "7",
"icao": "NTGA",
"direct_flights": "2",
"carriers": "1"
}
}
Just add these two listeners (and remove all that planningAppsSource.addEventListener stuff):
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(
evt.pixel, function(ft, l) { return ft; });
if (feature) {
// just to show all your feature's properties
console.log(feature.getProperties());
// to get a specific property
var name = feature.get('name');
var city = feature.get('city');
}
});
// you don't actually need this
// this is only to change the cursor to a pointer when is over a feature
map.on('pointermove', function(e) {
if (e.dragging) return;
var hit = map.hasFeatureAtPixel(map.getEventPixel(e.originalEvent));
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});

Amcharts - Maps: bad coordinates (lat/long) on a custom map (county level Romania)

I'm trying to add cities on a county map. The lat and long are drawn corectcly on the full size map(Romania level) but on the county map these are drawn wrong. I think I should rescale the map or lat/long of the city, I don't know...
How should I generate the county map in accordance with cities lat/long?
The code is listed below:
http://jsfiddle.net/xzAx7/33/
var map;
AmCharts.ready(function() {
map = new AmCharts.AmMap();
map.pathToImages = "http://www.ammap.com/lib/images/";
//map.panEventsEnabled = true; // this line enables pinch-zooming and dragging on touch devices
map.balloon.color = "#000000";
var wordlDataProvider = {
mapVar: AmCharts.maps.Cluj,
getAreasFromMap: true,
areas: [
{ id: "FR", color: "#4444ff" },
{ id: "RU", color: "#4444ff" },
{ id: "US", color: "#4444ff" }
],
images: [{
title: "ClujNapoca",
latitude: 46.85307355,
longitude: 23.63327696,
type: "circle",
color: "red",
scale: 0.5
}, {
title: "Turda",
latitude: 46.5745618,
longitude: 23.78573862,
type: "circle",
color: "red",
scale: 0.5
}]
};
map.dataProvider = wordlDataProvider;
map.areasSettings = {
autoZoom: true,
selectedColor: "#CC0000"
};
map.write("mapdiv");
});
I've found the solution. You need to define "defs" properties (leftLongiitude, ...) when you create a custom map. This is specified in this article - https://www.amcharts.com/tutorials/creating-custom-maps-for-javascript-ammap/
In the amCharts article is explained how you can get these "defs" properties.
I've changes the code below to understand how it works
"defs": {
"amcharts:ammap": {
"projection":"mercator",
"leftLongitude":"22.607117",
"topLatitude":"47.363798",
"rightLongitude":"24.261932",
"bottomLatitude":"46.384241"
}
}
demo: http://jsfiddle.net/xzAx7/35/

How to save markers position to localStorage in leaflet?

I am trying new to localStorage, and I am trying to save the markers that the user can create on the map.
I created this function to place markers and delete them:
var redmarker = L.icon({
iconUrl: 'http://icons.iconarchive.com/icons/paomedia/small-n-flat/48/map-marker-icon.png',
iconSize: [48, 48], // size of the icon
iconAnchor: [24, 48], // point of the icon which will correspond to marker's location
popupAnchor: [-2, -48] // point from which the popup should open relative to the iconAnchor
});
var popup = L.popup();
// On map click shows coordinates X, Y
function onMapClick(e) {
var geojsonFeature = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [e.latlng.lat, e.latlng.lng]
}
}
var marker;
L.geoJson(geojsonFeature, {
pointToLayer: function(feature, latlng){
marker = L.marker(e.latlng, {
title: "Resource Location",
alt: "Resource Location",
riseOnHover: true,
draggable: true,
icon: redmarker
}).bindPopup("<<span>X: " + e.latlng.lng + ", Y: " + e.latlng.lat + "</span><br><a href='#' id='marker-delete-button'>Delete marker</a>");
marker.on("popupopen", onPopupOpen);
return marker;
}
}).addTo(map);
}
function onPopupOpen() {
var tempMarker = this;
$("#marker-delete-button:visible").click(function () {
map.removeLayer(tempMarker);
});
}
map.on('click', onMapClick);
I am not familiar with localStorage, this is new to me. Also I am trying to make the popup editable, an user input there for the user name the marker.
I saw this example of input:
http://tahvel.info/simpleStorage/example/
Something like that.
A working example of my function: http://fiddle.jshell.net/2g4h5eu5/1/
Can someone help me save the markers in localStorage?
Also my problem is that I don't know what render's the markers on leaflet after I click, so I don't know exactly what I need to save in local storage to retrieve those markers.
you can use the following functions to manage your localStorage
localStorage.setItem('favoriteflavor','vanilla');
var taste = localStorage.getItem('favoriteflavor');
// -> "vanilla"
localStorage.removeItem('favoriteflavor');
var taste = localStorage.getItem('favoriteflavor');
// -> null
check this link
also you can use jQuery Storage API plugin to make things more cross-browser
http://fiddle.jshell.net/thesane/2g4h5eu5/29/
/// Load markers
function loadMarkers()
{
var markers = localStorage.getItem("markers");
if(!markers) return;
markers = JSON.parse(markers);
markers.forEach(function(entry) {
latlng = JSON.parse(entry);
var geojsonFeature = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [latlng.lat, latlng.lng]
}
}
var marker;
L.geoJson(geojsonFeature, {
pointToLayer: function(feature){
marker = L.marker(latlng, {
title: "Resource Location",
alt: "Resource Location",
riseOnHover: true,
draggable: true,
icon: redmarker
}).bindPopup("<<span>X: " + latlng.lng + ", Y: " + latlng.lat + "</span><br><a href='#' id='marker-delete-button'>Delete marker</a>");
marker.on("popupopen", onPopupOpen);
return marker;
}
}).addTo(map);
});
}
/// Store markers
function storeMarker(marker)
{
var markers = localStorage.getItem("markers");
if(!markers) {
markers = new Array();
console.log(marker);
markers.push(JSON.stringify(marker));
}
else
{
markers = JSON.parse(markers);
markers.push(JSON.stringify(marker));
}
console.log(JSON.stringify(markers));
localStorage.setItem('markers', JSON.stringify(markers));
}
// Delete Marker
function deleteMarker(lng, lat) {
var markers = localStorage.getItem("markers");
markers = JSON.parse(markers);
for(var i=0;i<markers.length;i++){
latlng = JSON.parse(markers[i]);
if(latlng.lat == lat && latlng.lng == lng)
{
markers.splice(i,1);
}
}
localStorage.setItem('markers', JSON.stringify(markers));
}

Use JavaScript to feed data into DOM?

In openstreetmap I'm using openlayer3 to display some data information about random building. It's a simple interaction, when you click on marker data will be presented.
I'm not good in JavaScript so I had some help, and after a while a set up everything like this, you can check it in this JSFIDDLE example.
So, I'm using ol.Feature.html#on to bind event to markers, and I'm loading data with info.innerHTML = "<h1>"+data.name+"</h1>", and everything is looking like this:
/* Create the map */
// setting up coordinates for map to display
var infobox = document.getElementById("info");
var city = ol.proj.transform([-73.920935,40.780229], 'EPSG:4326', 'EPSG:3857');
// setting up openlayer3 view
var view = new ol.View({
center: city,
zoom: 13
});
// Create the map
var map = new ol.Map({
target: 'map',
renderer: 'canvas',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: view
});
var Data =
[ { name: "foo",
address: "Some Random Address 1"
, longlat: [-73.927870, 40.763633]
}
, { name: "foo2",
address: "Some Random Address 2"
, longlat: [-73.917356, 40.763958]
}
, { name: "foo3",
address: "Some Random Address 3"
, longlat: [-73.915530, 40.779665]
}
, { name: "foo4",
address: "Some Random Address 4"
, longlat: [-73.916045, 40.779372]
}
, { name: "foo5",
address: "Some Random Address 5"
, longlat: [-73.919682, 40.777365]
}
, { name: "foo6",
address: "Some Random Address 6"
, longlat: [-73.908980, 40.776013]
}
];
function buildFeature(data) {
return new ol.Feature(
{ geometry: new ol.geom.Point(ol.proj.fromLonLat(data.longlat))
, data: data
}
);
}
function curryclickonmarker(element) {
return function (event) {
return clickOnMarker(element, event);
}
}
function clickOnMarker(info, event) {
// This is ugly!
var marker = event.selected[0];
var data = marker.G.data;
// Feed data into DOM
info.innerHTML = "<h1>"+data.name+"</h1>";
}
var selectClick = new ol.interaction.Select();
selectClick.on("select", curryclickonmarker(infobox));
// Setup markers
var features = Data.map(buildFeature);
var markers = new ol.layer.Vector({
tittle: 'City Apratments',
source: new ol.source.Vector({
features: features
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixel',
opacity: 0.75,
src: 'http://openlayers.org/en/v3.12.1/examples/data/icon.png',
})
})
});
map.addLayer(markers);
map.addInteraction(selectClick);
I would like to make this look better, it's looking very ugly, so I need someone to explain to me how can I pass multiple data for the marker, because currently I can only see foo, foo1, foo2, foo3, etc, I'm using openlayers3 API for event's, but can I use pure javascript for this so I can pass addres, pictures, description for the specific marked building, because I need to display a loot, I'm just having hard time understanding how to use javascript to pass more data?

Merge tool tip of overlapping Markers on Google Map

Currently, I am displaying 500-600 Markers on Google map, with their names as tooltip. Now,
I need to display the tool-tip of all overlapping markers as comma-separated i.e. Marker1, Marker2, Marker3 etc. if Marker1, Marker2, Marker3 are overlapped on map.
I found many other different examples on google map at internet especially at GeoCodeZip, but not of my requirement.
if this requirement is once filled, Am afraid of performance issues on zoom changed events, as tooltip needed to be updated (if overlapping is changed).
Update1 : I have already show Overlapping Marker spiderfier to client but not acceptable.
Does anyone have right path or working example ?
Thanks
-Anil
The core of this is to find the pixel distance between LatLngs. Then before adding each marker check the pixel distance between it and any existing markers. If there is another marker nearby add to the title otherwise create a new marker. jsFiddle
function init() {
var mapOptions = {
center: new google.maps.LatLng(0, -0),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
// to get the pixel position from the latlng
// https://stackoverflow.com/questions/1538681/how-to-call-fromlatlngtodivpixel-in-google-maps-api-v3
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
google.maps.event.addListenerOnce(map, 'idle', function() {
if (overlay.getProjection()) {
var points = [
{ latlng: new google.maps.LatLng(40, -100), title: '1' },
{ latlng: new google.maps.LatLng(40.125, -100.125), title: '2' },
{ latlng: new google.maps.LatLng(40.25, -100.25), title: '3' },
{ latlng: new google.maps.LatLng(40.5, -100.5), title: '4' },
{ latlng: new google.maps.LatLng(40.75, -100.75), title: '5' },
{ latlng: new google.maps.LatLng(41, -101), title: '6' },
{ latlng: new google.maps.LatLng(35, -95), title: '7' },
{ latlng: new google.maps.LatLng(45, 105), title: '8' },
{ latlng: new google.maps.LatLng(25, -115), title: '9' },
{ latlng: new google.maps.LatLng(55, -85), title: '10' },
{ latlng: new google.maps.LatLng(30, -34), title: '11' }
];
// for each point
var markers = [];
points.forEach(function (point) {
var nearby = false;
var pointPixelPosition = overlay.getProjection().fromLatLngToContainerPixel(point.latlng);
markers.forEach(function(marker) {
var markerPixelPosition = overlay.getProjection().fromLatLngToContainerPixel(marker.getPosition());
// check for marker 'near by'
if (Math.abs(pointPixelPosition.x - markerPixelPosition.x) < 10 || Math.abs(pointPixelPosition.y - markerPixelPosition.y) < 10) {
nearby = true;
marker.setTitle(marker.getTitle() + ', ' + point.title);
}
});
// create new marker
if (!nearby) {
markers.push(new google.maps.Marker({ map: map, position: point.latlng, title: point.title }));
}
});
}
map.setCenter(new google.maps.LatLng(39.8282, -98.5795));
});
}

Categories