Have the latitude and longitude of various places in a html table, on clicking the row,a function sends the latitude and longitude values to a javascript function which loads the openstreetmap map and marker in a bootstrap modal.
This works the first time the function is called, the marker is shown but on closing the modal and the function is called again I get the error
Uncaught Error: Map container is already initialized.
function sendlatlng(id) {
var geom=document.getElementById('cor'+id).value;
var geom1=document.getElementById('cod'+id).value;
var map = L.map(('map'),{scrollWheelZoom:true}).setView([geom,geom1], 12);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
maxZoom: 18
}).addTo(map);
L.marker([geom,geom1]).addTo(map);
}
Is there a way that the map div
<div id="map" class="map" style="height: 300px;"></div>
Is re initialized every time the modal is opened or the function is called.
The error coming from leaflet because we are trying to create a map container each time sendlatlng is executed. That's ok, because instead of trying to create the map and marker in the sendlatlng function, we can create those once, and then use the function to update the coordinates of the existing objects. Here is an example:
<html>
<head>
<title>A Leaflet map!</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.0.3/dist/leaflet.js"></script>
<style>
#map {
width: 450px;
height: 250px
}
</style>
</head>
<body>
<div id="map"></div>
<script>
//just for the demo
var defaultCoords = [-41.291, -185.229];
//set up our map
var map = L.map('map').setView(defaultCoords, 12);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
maxZoom: 18
}).addTo(map);
//this is how we are going to demo our sendlatlng function
map.on('click', onMapClick);
//use this variable to track our marker here outside of the sendlatlng function
var myMarker = L.marker(defaultCoords).addTo(map);
//in our example, we are going to listend for clicks on the map to trigger
//changes to the coords with our sendlatlng function
function onMapClick(e) {
sendlatlng(e.latlng)
}
//update the map and marker positions based on the coords passed to the function
//we will just update our existing map and myMarker variables instead of create new ones
function sendlatlng(coords) {
map.setView(coords, 12);
myMarker.setLatLng(coords);
}
</script>
</body>
</html>
In the demo, we are triggering the sendlatlng function with a mouse click on the map. This will recenter the map and move myMarker to the new center.
If, for example, you wanted to create a new marker in the click location, we could do that the same way you originally had your function: by adding a new marker: L.marker(coords).addTo(map);
If you create a map and try to map it again, you'll get this error. Try the following sample codes
//Use this before creating the map
if (map != undefined) {
map.remove();
}
//Use this after adding tile layer
setTimeout(function () { map.invalidateSize() }, 1200);
Related
I'm using Mapquest API and Leaflet to display a map with markers on a web page.
Leaflet reference: https://leafletjs.com/examples/quick-start/
The button should add a marker at the specified coordinate when the button is clicked. For some reason, it doesn't seem to be working. Here is my script:
var L;
window.onload = function() { //loads map, center etc.
L.mapquest.key = 'O5L5sKXrVY1AYIpiS2xVMvsLgAxUSw32';
var map = L.mapquest.map('map', {
center: [37.641313, -122.290785],
layers: L.mapquest.tileLayer('map'),
zoom: 10
});
//add markers and other map shapes here.
//trying to get it to add based on input.
document.getElementById('mrkbtn').onclick = function addMarker() {
L.marker(document.getElementById('inputText').value).addTo(map); }
}
and here is the HTML button:
<div class="centerBtn">
<input id="inputText" placeholder="insert coordinates"></input>
<button id="mrkbtn" onclick="addMarker()">Add Marker to Map</button>
</div>
<br>
<div id="map"></div>
The button will add a marker when there are coordinates inside of L.marker() as follows:
L.marker([37.641313, -122.290785]).addTo(map);
however, when I changed what is inside L.marker() to try to grab the input value, it does not work.
This is the part of the script where I'm making a mistake:
L.marker(document.getElementById('inputText').value).addTo(map);
I'm new to this, thanks so much for any assistance.
L.marker(...).addTo(map) needs an array of numbers. You are using the constructor in a wrong way.
Let's pretend that the coordinates in your input are separated by a comma like:
13.443521,42.112345
Your function should be something like that:
document.getElementById('mrkbtn').onclick = function addMarker() {
L.marker((document.getElementById('inputText').value).split(',')).addTo(map); }
}
This should work because the split function is returning an array.
I'm working with Ionic 3 and Angular 5 and I want to display a map on my app. I created a map component but I get troubles to display the map after a page refresh.
MapComponent
map.html
<div id="map" style="height:100%; width: 100%;"></div>
map.ts
Basically, I create a new raw map element to avoid intializing the map on the same HTML element, which causes a Leaflet error ("map container is already initialized")
ngOnInit() {
var map: any = null;
var mapElement = document.getElementById("map");
mapElement.parentElement.innerHTML = '<div id="map" style="height:100%; width: 100%;"></div>';
console.log("new map element created");
var initMap = function () {
console.log("init map..");
L.mapquest.key = 'XXXXXX';
map = L.mapquest.map('map', {
center: [37.7749, -122.4194],
layers: L.mapquest.tileLayer('map'),
zoom: 15
});
}
initMap();
}
Result
The map is correctly displayed the first time. But when I go back a second time on the page where the map is displayed, I don't get any error but I just get a blank div element, as if Leaflet could not init the map.
Also, in the console I see that the element is created before the map is initialized, so it should work.
Do you have any inputs to help me with this problem? Thanks in advance.
Try using ionViewDidEnter()
ionViewDidEnter() {
var map: any = null;
var mapElement = document.getElementById("map");
mapElement.parentElement.innerHTML = '<div id="map" style="height:100%; width: 100%;"></div>';
console.log("new map element created");
var initMap = function () {
console.log("init map..");
L.mapquest.key = 'XXXXXX';
map = L.mapquest.map('map', {
center: [37.7749, -122.4194],
layers: L.mapquest.tileLayer('map'),
zoom: 15
});
}
initMap();
}
ionViewDidEnter() runs whenever you enter the page, regardless if it was cached or not.
This is my first attempt working with javascript and GeoJSON by using leaflet.
So far, I got the desired map and the leaflet.draw plugin working in the way that I can draw a shape and it appears on my screen.
I tried to write this shape to a GeoJSON that I want to use in R.
Therfore I used the ideas presented here to create the GeoJSON string. I think the desired information for me is stored in the variable shape_for_db.
However, using Firebug in Firefox I am not able to find this variable.
Do I get something wrong here?
This is the script I am using:
<html>
<head>
<title>A Leaflet map!</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.css" />
<link rel="stylesheet" href="http://leaflet.github.io/Leaflet.draw/leaflet.draw.css" />
<script src="http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.js"></script>
<script src="jquery-2.1.1.min.js"></script>
<script src="http://leaflet.github.io/Leaflet.draw/leaflet.draw.js"></script>
<style>
#map{ width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// base map
var map = L.map('map').setView([51.25,10.57], 8);
// load a tile layer
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',
{
attribution: 'Tiles by: OpenStreetMaps',
maxZoom: 17,
minZoom: 5
}).addTo(map);
// Initialise the FeatureGroup to store editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
});
map.addControl(drawControl);
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
drawnItems.addLayer(layer);
});
// Shape to GeoJSON
map.on('draw:created', function (e) {
var type = e.layerType;
var layer = e.layer;
var shape = layer.toGeoJSON()
var shape_for_db = JSON.stringify(shape);
});
</script>
</body>
</html>
The scope for your shape_for_db is inside your second listener for draw-created. You can place on window.shape_for_db if you are doing this for a one-off experimental/playing around approach and want to use your dev console/Firebug. Or set up var shape_for_db outside the listener.
I want to connect my dynamic data with google map marker here is my code
this is my mapdata and listdata both having same value which coming from the php
latitude: "19.1904917"
logitude: "72.8639419"
name: "Monkey d luffy"
using this latitude and logitude i m showing google marker on map for show marker data i used this code
var defaultLatlng = new google.maps.LatLng(19.0822508,72.8812041);
var myOptions = {
zoom: 10,
panControl:false,
streetViewControl:false,
center: defaultLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl:true,
zoomControlOptions: {
style:google.maps.ZoomControlStyle.SMALL
},
};
loadMap();
function loadMap(){
console.log('loadMap');
// create new map make sure a DIV with id myMap exist on page
map = new google.maps.Map(document.getElementById("myMap"), myOptions);
geocoder = new google.maps.Geocoder();
//oms = new OverlappingMarkerSpiderfier(map,{markersWontMove: true, markersWontHide: true});
// create new info window for marker detail pop-up
$.each(mapdata.locations,function(key,val){
loadMarker(val);
});
$.each(listdata.locations,function(key,val){
loaddata(val);
});
}
this is my loadmarker function which showing marker on google maps
function loadMarker(markerData)
{
var myLatlng = new google.maps.LatLng(markerData['latitude'],markerData['logitude']);
console.log(myLatlng);
// create new marker
var marker = new google.maps.Marker({
map: map,
title: markerData['address'],
position: myLatlng
//animation:google.maps.Animation.BOUNCE
});
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/red-dot.png');
gmarkers.push(marker);
var marker_num = gmarkers.length-1;
google.maps.event.addListener(marker, 'click', function() {
showMarker(markerData,marker);
});
}
this is my loaddata function which is showing my data on UI
function loaddata(markerData)
{
listitem += "<div class='expert_name'>"
+markerData['name']+
+"</div>"
$('#_mymaplist').html(listitem);
}
this is my html where i add all this thing
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Multiple Markers Google Maps</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false" type="text/javascript"></script>
</head>
<body>
<div id="mymap" style="width: 800px; height:500px;"></div>
<div id="_mymaplist" style="width: 800px; height:500px;"></div>
</body>
</html>
i want when i hover name from _mymaplist div then google marker color has to change for the example here i only give one data but there will be more than one
i checked many example like this but i won't work for me
because this example having same function for loading the data..but in my case i have 2 function to load data. i also can use 1 function but problem is that map marker loading all data at one time and the list data is using pagination form loading data....so that y i can't use same function for loading data Please help me
Because of the issue of pagination if you have to use 2 functions, you can use the Styled Marker in the loaddata() function itself where you are defining your individual markers. For that you will need to use set(property, value) methods.
this.styleIcon.set('color', '00fff0');
This has to be defined inside your loaddata() function where your listitems are initialized.
function createStyle() { return new StyledIcon(StyledIconTypes.BUBBLE,{color:"#95AA7B",text:"click me!",fore:"#ffffff"}); }
listitem += "<div class='expert_name'>"
+markerData['name']+
+"</div>"
$('#_mymaplist').html(listitem);
google.maps.event.addDomListener(marker4,"click", function(o){
this.styleIcon.set("fore","#ffffff");//test color
this.styleIcon.set("color","#C2554D");// background color
this.styleIcon.set("text","color changed");
});
Hope this would Help!!
Hi I am showing some markers on my google map and on click of the marker, I am calling the click event and showing some info about that place to the right side(area other than Map and not as an infoWindow). Now this event gets fired on click, and by default when page loads my div remains blank, How can I have the div the basic information being shown up once the map loads up. I need to show the information that corresponds to the marker that is the center point of the map, and later when the users click the marker icons the info should change and correspond to the particular marker being clicked
I have tried something but it doesn't work:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var places = [];
places.push(new google.maps.LatLng(51.43581, -0.51744));
places.push(new google.maps.LatLng(48.87187, 2.31764));
places.push(new google.maps.LatLng(45.45979, 9.19681));
var infowindow;
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
}
}
$("document").ready(function () {
loadMap();
});
UPDATE EDITED
Basically I need something like Layer KML features
But the info should come on the right hand side by default for the first time. Later on when the marker is clicked, the info should change. I am also not adamant that I need this info in a kml file(xml is fine with me as well). I can just have a marker and info should popup on click and for the first time be default as well depending on the location of the user.
Bottom Line: I need the info to appear on click of a marker and by default when the page loads the info should appear corresponding to the center point of the map. which means users coming from different locations will see different info's corresponding to their location from where they are coming.(I am centering the map based on users location)
You can use the addDomListener event of the google maps api. Something like this:
<script>
function initialize() {
// Map initialization
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
<div id="map_canvas"></div>
</body>
Although the above code is Maps Javascript API code, the addDomListener() method binds to the window object of the browser and allows the API to communicate with objects outside of the API's normal domain.
further reading
Actually the basic Idea is that you need to read an XMl and parse the data and and show this in a seperate div on right side., This div you can create dynamically when you load the map e-g:
$("#body").append("<div class='newdiv'></div>")
From the google Docs in the section about InfoWindow:
Note that if you call open() without passing a marker, the InfoWindow
will use the position specified upon construction through the
InfoWindow options object.
So in your code, why don't you simply init your infoWindow and call the open() method? I am not particularly familiar with the api, but how about:
var infowindow = new google.maps.InfoWindow({
content: 'your initial text'
});
infowindow.open();
Or if you need the marker for special purposes on the infowindow, init an marker with the center position and use that in the infowindow.open(your_initial_pos) call.
You can use jQuery to .triger() a click event on the first marker on document.ready:
$(marker).trigger('click');
This will run the code you have already written and make it so when the page loads your div will be populated with data from whatever element you trigger the click on.
When you bind to document.ready you don't need encapsulate document in quotes:
$(document).ready(function () {...});
Or you could use the short-hand if you're into that sort of thing:
$(function () {...});
UPDATE
You can place the trigger function call after your for loop where you are setting up the markers:
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
//only run on the first marker
if (i === 0) {
//trigger a click event to show the first info-window
$(marker).trigger('click');
}
}
You can fire a tilesloaded event on the map object. Check out the Map reference for events
tilesloaded waits until the map tiles are actually loaded before firing. Using your code, you could do something like this:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
google.maps.event.addListener(map, 'tilesloaded', function() {
doSomething();
});