I am creating a map that consists of three maps and markers total that can be switched between like in this leaflet example, although when I test it, instead of the each map rendering as a single version filling the map frame they display as many multiple in a tile layout. Below is my code I am currently using, note that the images I am using for the maps are not actually maps thus I am using the 'L.CRS.Simple'.
This is the result I was expecting (sans the makers and with my images), maybe someone can spot where I went wrong?
-
<html>
<head>
<title>Interactive Map</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet.js" integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log==" crossorigin=""></script>
<style>
#map {
width: 1000px;
height: 1000px;
}
</style>
</head>
<body>
<div id="map">
<script>
var map1 = L.tileLayer('map1.png');
var map2 = L.tileLayer('map2.png');
var map3 = L.tileLayer('map3.png');
var markers = L.layerGroup(); //Leaving empty for the time being, using just to create check box in menu
var map = L.map('map', {
crs: L.CRS.Simple,
layers: [map1, map2, map3, markers],
maxZoom: 5
});
var baseMaps = {
"Map 1": map1,
"Map 2": map2,
"Map 3": map3
};
var overlayMaps = {
"Markers": markers
};
var bounds = [[0,0], [1000,1000]];
L.control.layers(baseMaps, overlayMaps, bounds).addTo(map);
map.fitBounds(bounds);
</script>
</div>
</body>
Yes, I am using locally stored images, no, I do not have images setup to use the standard URL format, if you choose to try my code just sub in 3 random pictures.
Here is a pic of what is occurring:
You forgot a 's' to markers
var overlayMaps = {
"Markers": markers
};
It should work now ;)
Related
Using latest leaflet library, I generated a plot in python from a GraDs file and supposedly I have the correct corners or bounds, but when overlaying in leaflet does not fit.
here is the simple code
<!DOCTYPE html>
<html>
<head>
<title>Image Overlay Example</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<style type="text/css">
html,
body,
#map {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div id = "map"></div>
<script>
// Creating map options
var mapOptions = {
center: [14, -85],
zoom: 5
}
var map = new L.map('map', mapOptions); // Creating a map object
// Creating a Layer object
// var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
// map.addLayer(layer); // Adding layer to the map
var esriImages = new L.TileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}');
var esriLabels = new L.TileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}');
var esri = L.layerGroup([esriImages, esriLabels]);
//default basemap
map.addLayer(esri);
// Creating Image overlay
var imageUrl = 'https://i.imgur.com/KNTRLHR.png';
var imageBounds = [[30,-115], [6,-59.03836]];
var overlay = L.imageOverlay(imageUrl, imageBounds,{ opacity:.7});
overlay.addTo(map);
map.on('click', function(e) {
// var popup = L.popup()
// .setLatLng(e.latlng)
// .setContent('<p>Hello, world!</p>')
// .openOn(map);
console.log ('click en ',e.latlng);
});
</script>
</body>
</html>
The representation of the image is like this as per NOAA site but is poor quality and also if i overlay does not fit.
What is the issue or how to fix it.
Thanks for any help
Edited: 2020.10.17 04Z
I am building a WordPress plugin that involves the use of maps and user created custom markers. I want to separate the map from the marker so that a user can create custom markers cross map platform and keep the marker data on there WordPress page.
I set up a development server on a raspberry pi 3 B, with a 2 Terabyte hard drive that it boots from. I set up an OpenStreetMap tile server of North America to practice on and I got it up and through and html file in my /var/www/html that runs through a LAMP server that also includes my WordPress development web server.
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Public Transport Lines - ÖV-Linien - openptmap.org</title>
<link rel="shortcut icon" href="favicon_pt.png">
<link rel="stylesheet" href="style.css" type="text/css">
<style> /* avoid empty tiles */ .olImageLoadError {display: none;}
</style>
<script src="OpenLayers.js" type="text/javascript"></script>
<script src="OpenStreetMap.js" type="text/javascript"></script>
<script type="text/javascript">
var map;
function init() {
// The overlay layer for our marker, with a simple diamond as symbol
var overlay = new OpenLayers.Layer.Vector('Overlay', {
styleMap: new OpenLayers.StyleMap({
externalGraphic: '../img/marker.png',
graphicWidth: 20, graphicHeight: 24, graphicYOffset: -24,
title: '${tooltip}'
})
});
// The location of our marker and popup. We usually think in geographic
// coordinates ('EPSG:4326'), but the map is projected ('EPSG:3857').
var myLocation = new OpenLayers.Geometry.Point(10.2, 48.9)
.transform('EPSG:4326', 'EPSG:3857');
// We add the marker with a tooltip text to the overlay
overlay.addFeatures([
new OpenLayers.Feature.Vector(myLocation, {tooltip: 'OpenLayers'})
]);
// A popup with some information about our location
var popup = new OpenLayers.Popup.FramedCloud("Popup",
myLocation.getBounds().getCenterLonLat(), null,
'<a target="_blank" href="http://openlayers.org/">We</a> ' +
'could be here.<br>Or elsewhere.', null,
true // <-- true if we want a close (X) button, false otherwise
);
// Finally we create the map
map = new OpenLayers.Map({
div: "map", projection: "EPSG:3857",
layers: [new OpenLayers.Layer.OSM(), overlay],
center: myLocation.getBounds().getCenterLonLat(), zoom: 15
});
// and add the popup to it.
map.addPopup(popup);
}
</script>
</head>
<body onload="init();">
<div style="width:100%; height:100%;" id="map"></div><br></body>
</html>
This is an example of the example marker that I created which I can use a short code to link to in my plugin, but I can't get scripts to run in the plugin itself with results on the map.
For example when I run this script in my plugin attached to just a plain map.html iframe it doesn't do anything.
Hi I am using the following https://github.com/perliedman/leaflet-control-geocoder to get the location on map. But When I get the result I want to have the option to move the marker so I can adjust the coordinates. I found a code that is moving the marker and shows the coordinates in a 2 fields but I have problem to join the two codes together. Also how I get the results coordinates to show in the two flields. I dont have much experience with leaflet maps so any help would be appreciated.
Thank you
Dany
my code:
<html lang="en">
<head>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link rel="stylesheet" href="assets/css/leaflet-control-geocoder.css" />
</head>
<body>
<div class="map" id="map" style="width: 600px; height: 400px"></div>
<input id="latitude" type="text" name="latitude" />
<input id="longitude" type="text" name="longitude" />
</body>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="assets/js/leaflet-control-geocoder.js"></script>
<script type="text/javascript">
var map = L.map('map').setView([0, 0], 2);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
L.Control.geocoder().addTo(map);
var marker = L.marker([51.441767, 5.470247],{
draggable: true
}).addTo(map);
marker.on('dragend', function (e) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
});
</script>
</html>
Simply refer to Leaflet Control Geocoder API.
You can customize what the plugin does with the result it receives from the search request. By default it creates a (fixed) marker, binds a popup and opens it.
In your case, you could do:
var geocoder = L.Control.geocoder().addTo(map),
latInput = document.getElementById('latitude'),
lngInput = document.getElementById('longitude'),
previousMarker;
// Customize what to do from the result.
geocoder.markGeocode = function (result) {
var latlng = result.center;
// Remove previous marker if any.
if (previousMarker) {
map.removeLayer(previousMarker);
}
previousMarker = L.marker(latlng, {
draggable: true // Create a draggable marker.
}).addTo(map).
on('dragend', onDragEnd). // Attach position display.
bindPopup(result.html). // Emulate Geocoder default behaviour.
openPopup(); // bind a popup and open it right away.
displayLatLng(latlng); // Display position right away.
};
function onDragEnd(event) {
var latlng = event.target.getLatLng();
displayLatLng(latlng);
}
function displayLatLng(latlng) {
latInput.value = latlng.lat;
lngInput.value = latlng.lng;
}
Demo: http://jsfiddle.net/ve2huzxw/11/
I am using Leaflet library recently, i find it very easy to work and learn, the tutorials are very good with GeoJSON and Control Layers, but i not find one tutorial about the use of control layers with GeoJASON files, i write this script:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="leaflet.css"/>
<script src="leaflet-src.js"></script>
<script src="GeoJason/mpios.geojson"type="text/javascript"></script>
<script src="GeoJason/roads.geojson"type="text/javascript"></script>
<script src="GeoJason/city.geojson"type="text/javascript"></script>
<script src="GeoJason/towns.geojson"type="text/javascript"></script>
<style>
html, body, #map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var map = L.map('map').setView([20.990584, -98.65644], 12);
L.geoJson(mpios).addTo(map);
L.geoJson(roads).addTo(map);
L.geoJson(city).addTo(map);
L.geoJson(towns).addTo(map);
var baseLayers = {
"roads": roads,
"mpios": mpios
};
var overlays = {
"city": city,
"towns": towns
};
L.control.layers(baseLayers, overlays).addTo(map);
</script>
</body>
</html>
but it display the layers and the control buttons not work, thx.
The layer values you are setting in your baseLayers and overlays is your geoJSON feature sets, but they should be leaflet layers or references to layers that exists on your map.
You can store the layer refernece for each of your geoJSON layers by setting the return value from L.geoJson to a variable like this:
var mpios_l = L.geoJson(mpios).addTo(map);
var roads_l = L.geoJson(roads).addTo(map);
var city_l = L.geoJson(city).addTo(map);
var towns_l = L.geoJson(towns).addTo(map);
Then add these items to your control.
var baseLayers = {
"roads": roads_l,
"mpios": mpios_l
};
var overlays = {
"city": city_l,
"towns": towns_l
};
L.control.layers(baseLayers, overlays).addTo(map);
I have the following page, which by defaults opens a map centered on France:
http://www.villasdirect.com/_admin/dev/Country_MapV3.asp
It does seem to auto zoom to a certain extent, however when I look at France or Germany (just a couple of examples) the countries are not zoomed in close enough. If I search London however, it seems to be pretty much perfect - as in filling the box with a map of London.
You can see the different results here:
http://www.villasdirect.com/_admin/dev/Country_MapV3.asp?l=france
What I am aiming to do is the fill the map with the country, town or region, when selected... possible?
Help appreciated as always!
Here is my code too:
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
location = request.QueryString("l")
if location = "" then location = "France"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
<div id="map" style="width: 800px; height: 600px"></div>
<form onsubmit="showAddress(); return false" action="#">
<input id="search" size="60" type="hidden" value="<%=location%>" />
</form>
<div id="message"></div>
<noscript><b>JavaScript must be enabled in order for you to use Google Maps.</b>
However, it seems JavaScript is either disabled or not supported by your browser.
To view Google Maps, enable JavaScript by changing your browser options, and then
try again.
</noscript>
<script type="text/javascript">
//<![CDATA[
var xmlsource = '<markers><marker Town="Fayence" Region="Provence - Var" type="green" lng="6.694103" lat="43.624076"/><marker Town="La Cadiere d\'Azur" Region="Provence - Var" type="green" lng="5.755173" lat="43.196218"/><marker Town="Villefranche Du Périgord" Region="South West France" type="green" lng="1.080006" lat="44.62966"/><marker Town="Limetz-Villez" Region="Paris" type="green" lng="1.547366" lat="49.029137"/><marker Town="Boulogne-Billancourt" Region="Paris" type="green" lng="2.237803" lat="48.84325"/><marker Town="Saint-Germain-En-Laye" Region="Paris" type="green" lng="2.0934031" lat="48.8955155"/></markers>'
var myOptions = {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var infoWindow = new google.maps.InfoWindow;
$( $.parseXML( xmlsource ) ).find("marker").each(function() {
var lng = $(this).attr('lng');
var lat = $(this).attr('lat');
marker = new google.maps.Marker({
map:map,
draggable:true,
animation: google.maps.Animation.DROP,
position: new google.maps.LatLng(59.32522, 18.07002)
});
});
google.maps.event.addListener(marker, 'click');
// ====== Create a Client Geocoder ======
var geo = new google.maps.Geocoder();
geo.geocode({'address': document.getElementById("search").value}, function (results, status) {
var ne = results[0].geometry.viewport.getNorthEast();
var sw = results[0].geometry.viewport.getSouthWest();
map.fitBounds(results[0].geometry.viewport);
placeMarkers();
});
function placeMarkers(){
var xmlList = $.parseXML(xmlsource);
var markers = $(xmlList).find('marker');
for (var i = 0; i < markers.length; i++) {
var latlng = new google.maps.LatLng(parseFloat($(markers[i]).attr("lat")),
parseFloat($(markers[i]).attr("lng")));
var type = $(markers[i]).attr("type");
var imgnam = "";
if(type == "green") {
imgnam = "http://openmbta.org/images/map/PinDown1Green.png?1306943843";
}else{
imgnam = "http://openmbta.org/images/map/PinDown1.png?1306943843";
}
var img = new google.maps.MarkerImage(
imgnam,
new google.maps.Size(30,35),
new google.maps.Point(0,0),
new google.maps.Point(15,35)
);
//add a link to your xml that can be inserted here where I have http://www.google.com
var html = "<a href='http://www.google.com'>" + $(markers[i]).attr('Region') + ', ' + $(markers[i]).attr('Town') + "</a>";
var marker = new google.maps.Marker({position: latlng, map: map, icon: img, html:html});
var infowindow1 = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow1.setContent(this.html);
infowindow1.open(map, this);
});
}
}
</script>
</body>
</html>
It's an old question but I think I have an answer. Instead of this:
map.fitBounds(results[0].geometry.viewport);
try this:
map.fitBounds(results[0].geometry.bounds);
According to Google Maps API documentation results.geometry.bounds may return a slightly different viewport. It's not exactly a solution, but it's worth a try.
Moreover, as I understand, Google Maps doesn't have imagery at infinite zoom levels and when fitBounds() is invoked, it will automatically select the highest zoom level that contains the given bounds and at which imagery is available. In your case, the bounds are the border of France and the viewport fits the border of France at the current zoom level. If you go just one zoom level further, the boundaries of France go out of the viewport.
You can change the size of viewport. For a certain size of viewport (I can't say exactly what size) you might achieve a perfect fit. You cited an example of London. I'm sure that for certain viewport sizes, London doesn't perfectly fit the viewport either. So, it's by chance that you came across a viewport size that is perfect for London.
If you still want more zoom, and can't change the viewport size, I suggest you try getZoom() then increment the result by 1 and setZoom(). Then again, that renders the border areas out of the viewport.
Cheerio!
Afaik there is no way of getting the information as to the physical dimensions of an area (be it city/county/country) from google.
If you had a database yourself with the sizes for every city/state/country combo then I guess you could do it with comparisons.
Otherwise, you're pretty much stuck with this one.