I am using leaflet.draw lib. and trying to built drawing toolbar on the simple image, it displaying fine but its action doesn't works.
<div id='image-map'></div>
and my script is
<script>
url = 'images/leafletTest.png';
var bounds = [[-26.5,-25], [1021.5,1023]];
var image = L.imageOverlay(url, bounds);
map = new L.Map('image-map', {layers: [image], crs: L.CRS.Simple, minZoom : -5});
map.fitBounds(bounds);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
// Set the title to show on the polygon button
L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
polyline: false,
polygon: false,
circle: false,
marker: true
},
edit: {
featureGroup: drawnItems,
remove: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
drawnItems.addLayer(layer);
});
map.on(L.Draw.Event.EDITED, function (e) {
var layers = e.layers;
var countOfEditedLayers = 0;
layers.eachLayer(function (layer) {
countOfEditedLayers++;
});
console.log("Edited " + countOfEditedLayers + " layers");
});
</script>
when ever i draw a rectangle or marker it doesn't display.
Related
good morning
I am trying to use Leaflet to paint an image and save the figures, I have created the following method to start the map:
initmap()
{
var url = 'http://kempe.net/images/newspaper-big.jpg';
var bounds = [[-26.5,-25], [1021.5,1023]];
var image = L.imageOverlay(url, bounds);
var map = new L.Map('image-map', {layers: [image], crs: L.CRS.Simple, minZoom : -5});
map.fitBounds(bounds);
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
polyline: true,
polygon: false,
circle: false,
marker: true
},
edit: {
featureGroup: drawnItems,
remove: true
}
});
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
drawnItems.addLayer(layer);
var type = e.layerType
var shape = layer.toGeoJSON()
var shape_to_json = JSON.stringify(shape);
this.currentMap = shape_to_json;
});
map.on(L.Draw.Event.EDITED, function (e) {
var layers = e.layers;
var countOfEditedLayers = 0;
layers.eachLayer(function (layer) {
countOfEditedLayers++;
});
});
}
As you can see there is an event definition for what to do when someone is drawing, (map.on(L.Draw.Event.CREATED, function (e) )
The point is that I log that method, with console.log to check what is saving in
this.currentMap = shape_to_json;
As you can see:
shape_to_json
installations-management.component.ts:120 {"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[421.202413,315.527832],[421.202413,756.416626],[988.101415,756.416626],[988.101415,315.527832],[421.202413,315.527832]]]}}
Everything seems ok. But when I click on the save button, the data of this.currentMap is missing, and in no other point is being modifidied.So, am I saving it wrong or is modified somewhere because of the event?
Thank you all !
I use OpenLayers map and I would like to get some text from var informations after click to marker. I think thant I need to have "general" function about singleclick in cycle for, because I need do it for each index [i]. But If I click to some marker I don´t see any information.
I tried to move "general" function to down before console.table(window.phpdata.markers). When I run it, I can see last text from "informations" after click on each marker --> there isn´t any problem with getting data from databases.
(This isn´t required result because I don´t want to see last marker. I would like to see relevant text from informations for relevant marker. So with same index [i].
What to do for this result? Thank´s
Object.defineProperty(window.phpdata, "markers", {value: <?php echo !empty($list) ? json_encode($list) : 'null'; ?>, writable: false, configurable: false});
var base = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map = new ol.Map({
target: 'map',
layers: [base],
view: new ol.View({
center: ol.proj.fromLonLat([-74.0061,40.712]), zoom: 2
})
});
var vectors = new ol.source.Vector({});
if(window.phpdata.markers && window.phpdata.markers.length > 0) {
var data = window.phpdata.markers;
for(var i = 0; i < data.length; i++) {
var informations = data[i].info;
var marker = new ol.Feature({
geometry: new ol.geom.Point(
ol.proj.fromLonLat([Number(data[i].lng), Number(data[i].lat)])
),
});
marker.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
src: 'dot.png'
}))
}));
vectors.addFeature(marker);
marker.on('singleclick', function (event) { //general function to move..
if (map.hasFeatureAtPixel(event.pixel) === true) {
document.getElementById("www").innerHTML=informations;
} else {
overlay.setPosition(undefined);
closer.blur();
}
}); // //to there
}
var layer = new ol.layer.Vector({
source: vectors,
});
map.addLayer(layer);
}
document.getElementById('myposition').innerText = "click to map and get coordinates here";
map.on('singleclick', event => {
const coordinate = ol.proj.toLonLat(event.coordinate);
//const innerText = `Lon: ${coordinate[0].toFixed(4)}, Lat: ${coordinate[1].toFixed(4)}`;
const innerText = `${coordinate[0].toFixed(4)}, ${coordinate[1].toFixed(4)}`;
document.getElementById('myposition').innerText = innerText;
});
map.on('pointermove', function(evt) {
map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : '';
});
console.table(window.phpdata.markers)
Features do not have click events. You need to check if there are features where you click the map. You can add the info as a property to the feature and use get() to display it.
for(var i = 0; i < data.length; i++) {
var marker = new ol.Feature({
geometry: new ol.geom.Point(
ol.proj.fromLonLat([Number(data[i].lng), Number(data[i].lat)])
),
info: data[i].info
});
}
....
....
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature) {
return feature;
});
if (feature) {
document.getElementById("www").innerHTML = feature.get('info');
....
};
});
When using leaflet v0.7.7 then leaflet-indoor works perfectly.
After updating to leaflet v1.0.3 markers become draggable, but now leaflet-indoor is not working.
Moreover, leaflet itself is throwing an error:
TypeError: Cannot read property 'call' of undefined
const MapController = function() {
// Containers
var $window = $(window),
mapEl = document.getElementById('map-base'),
mapFileName = window.mapFile,
resourceSidebar = document.getElementById('resourceSidebar'),
detailSidebar = document.getElementById('detailSidebar');
// Links
var addResource = document.querySelectorAll('[data-add-resource]');
setHeight();
// Create map perimeter
// console.log(window);
var view = window.mapDefaultView.split(',');
var map = new L.Map(mapEl, {
center: new L.LatLng(parseFloat(view[0]),parseFloat(view[1])),
zoom: parseFloat(window.mapDefaultZoom),
zoomControl: true
});
makePerimeter()
L.marker([parseFloat(view[0]),parseFloat(view[1])], {
draggable: true,
icon: L.divIcon({
iconSize: null,
html: "<div style='padding:1rem'>Hi</div>"
})
}).addTo(map);
// Not draggable
// Just here for visual reference
// when dragging marker
var circle = L.circle([parseFloat(view[0]),parseFloat(view[1])],100000).addTo(map);
L.control.mousePosition().addTo(map);
// Set heights on the main containers
function setHeight() {
var winHeight = $window.height()+'px';
mapEl.style.height = winHeight;
resourceSidebar.style.height = winHeight;
detailSidebar.style.height = winHeight;
}
// Open the detail sidebar
function toggleDetailSidebar() {
var el = detailSidebar;
if (el.classList.contains('active')) {
el.classList.remove('active');
} else {
el.classList.add('active');
}
}
// Create Perimeter, Guides, and Sections
function makePerimeter() {
$.get(window.mapDataFilePath, function(data) {
var baseLayer = new L.Indoor(data, {
getLevel: function(feature) {
if (feature.properties.relations.length === 0)
return null;
return feature.properties.relations[0].reltags.level;
},
onEachFeature: function(feature, layer) {
layer.bindPopup(JSON.stringify(feature.properties, null, 4));
},
style: function(feature) {
var fill = '#fafafa',
stroke = '#4d4d4d',
part = feature.properties.tags.buildingpart;
switch (part) {
case 'guide':
fill = '#eee';
stroke = '#eee';
break;
case 'section':
fill = 'transparent';
stroke = 'transparent';
break;
}
return {
fillColor: fill,
weight: 1,
color: stroke,
fillOpacity: 1
};
}
});
baseLayer.setLevel("0");
baseLayer.addTo(map);
var levelControl = new L.Control.Level({
level: "0",
levels: baseLayer.getLevels()
});
// Connect the level control to the indoor layer
levelControl.addEventListener("levelchange", baseLayer.setLevel, baseLayer);
levelControl.addTo(map);
perimeterWasMade()
});
}
function perimeterWasMade() {
// Save map view/zoom in hash, so it presists on refresh
var saveView = new L.Hash(map);
// Some other plugins I was messing around with
// Leave commented for now
//L.control.polylineMeasure({imperial: true}).addTo(map);
//L.control.mousePosition().addTo(map);
// 6' booth example
// This is the correct w/h of a 6'w booth that is 4'h
// except it is rotated incorrectly.
// It should be wider than it is tall.
var bounds = [
[ -0.0807 , 12.8787 ],
[ -0.0807 , 13.2845 ],
[ 0.5284 , 13.2845 ],
[ 0.5284 , 12.8787 ]
];
var booth = L.polygon(bounds, {color: 'red', weight: 1})
booth.addTo(map);
// Load booths
loadObjects()
}
function loadObjects() {
// load booths and prizes onto the map
loadJSON("booths.json", function(response) {
var actual_JSON = JSON.parse(response);
$.each(actual_JSON,function(i,val){
if (val.coordinate != undefined && val.size != null)
{
var size = val.size.split('x');
var marker = L.marker([val.coordinate.x,val.coordinate.y], {
id: val.id,
draggable: true,
icon: L.divIcon({
iconSize: null,
html: "<div style='height:"+size[0]+"; width="+size[1]+";'><div style=' padding:5px 10px;'>"+val.vendor.industry +" </div><span style='text-align:center;display:block;border-top:4px solid #888;'>"+val.vendor.name+"</span></div>"
})
}).addTo(map);
// label.dragging.enable();
marker.on('drag', function(event){
console.log("position");
});
//also display booths using leaflet.label
// var label = new L.Label();
// label.setContent("<div style='height:"+size[0]+"; width="+size[1]+";'><div style=' padding:5px 10px;'>"+val.vendor.industry +" </div><span style='text-align:center;display:block;border-top:4px solid #888;'>"+val.vendor.name+"</span></div>");
// label.setLatLng([val.coordinate.x,val.coordinate.y]);
// map.showLabel(label);
}
})
});
}
map.on('click', function(e) {
//alert(e.latlng);
});
// Catch click on resource in sidebar
if (addResource.length > 0) {
addResource.each(function() {
this.addEventListener('click', function(e) {
e.preventDefault();
mapEl.classList.add('adding-booth');
});
});
}
}
I want to get the Feature of a Layer by coordinate.
Furthermore I want to open this feature in a popup, which I have solved so far by an onclick event. But I want to realize by giving the coordinates of a feature and opening the popup of the featue.
I have a layer with the map and a layer with the features:
if (trackMap != null) {
for (var i = 0; i < trackMap.length; i++) {
var trackInfo = trackMap[i];
lat = parseFloat(trackInfo.lat);
lon = parseFloat(trackInfo.lon);
var layergpx = new ol.layer.Vector({
source: new ol.source.Vector({
parser: new ol.parser.GPX(),
url: '${contextRoot}/gps/gpx2' + trackInfo.url
})
});
layers.push(layergpx);
}
}
I want to get the feature of this layer in another Javascript function.
How I open a pop up by clicking on the map:
/**
* The Click Event to show the data
*/
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: ol.OverlayPositioning.BOTTOM_CENTER,
stopEvent: false
});
map.addOverlay(popup);
map.on('singleclick', function(evt) {
map.getFeatures({
pixel: evt.getPixel(),
layers: vectorLayers,
success: function(layerFeatures) {
var feature = layerFeatures[0][0];
if (feature) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.get('desc')
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
}
});
});
But I want this feature not to be opened by clicking on it on the map, but by entering a coordinate in a textfield and the map opens this pop up, like in the onclick event.
Take a look at this example to see if it helps you:
http://openlayers.org/en/latest/examples/kml.html
var displayFeatureInfo = function(pixel) {
map.getFeatures({
pixel: pixel,
layers: [vector],
success: function(featuresByLayer) {
var features = featuresByLayer[0];
var info = [];
for (var i = 0, ii = features.length; i < ii; ++i) {
info.push(features[i].get('name'));
}
document.getElementById('info').innerHTML = info.join(', ') || ' ';
}
});
map.getFeatures() has this success callback where it delivers the features of the layers specified in layers: [vector]. Customize it at will to get what you need.
=== Update ===
In the OpenLayers 3's Map object you have a function: getPixelFromCoordinate
/**
* #param {ol.Coordinate} coordinate Coordinate.
* #return {ol.Pixel} Pixel.
*/
ol.Map.prototype.getPixelFromCoordinate = function(coordinate) {
var frameState = this.frameState_;
if (goog.isNull(frameState)) {
return null;
} else {
var vec2 = coordinate.slice(0, 2);
return ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, vec2, vec2);
}
};
I have the below code in openlayers
<script defer="defer" type="text/javascript">
var map = new OpenLayers.Map('map');
var wms = new OpenLayers.Layer.WMS("OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0", { layers: 'basic' });
var dm_wms = new OpenLayers.Layer.WMS(
"Canadian Data",
"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap",
{
layers: "bathymetry,land_fn,park,drain_fn,drainage," +
"prov_bound,fedlimit,rail,road,popplace",
transparent: "true",
format: "image/png"
}, { isBaseLayer: true }
);
var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
map.setBaseLayer(vectorLayer);
OpenLayers.Geometry.Point(77.391026, 28.535516), { some: 'data' }, { externalGraphic: 'Image/map-icons/Banquet_and_Marriage_halls.png', graphicHeight: 21, graphicWidth: 21 });
var center = new OpenLayers.Geometry.Point(77.391026, 28.535516);
center.transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
map.setCenter(new OpenLayers.LonLat(77, 28), 4);
var markers = new OpenLayers.Layer.Markers("Markers");
var ll = new OpenLayers.LonLat(77.391026, 28.535516);
var popupClass = OpenLayers.Popup.Anchored;
var popupContentHTML = '<div style="height:40px;">Hello Noida</div>';
addMarker(ll, popupClass, popupContentHTML, true);
ll = new OpenLayers.LonLat(74.613647, 30.914007);
popupClass = OpenLayers.Popup.Anchored;
popupContentHTML = '<div style="height:40px;">Hello Punjab</div>';
addMarker(ll, popupClass, popupContentHTML, true);
map.addLayers([wms, dm_wms, markers]);
var feature;
var popup = null;
function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow) {
feature = new OpenLayers.Feature(markers, ll);
feature.closeBox = closeBox;
feature.popupClass = popupClass;
feature.data.popupContentHTML = popupContentHTML;
feature.data.overflow = (overflow) ? "auto" : "hidden";
var marker = feature.createMarker();
var markerClick = function (evt) {
//alert(popup);
if (popup != null)
popup.hide();
popup = this.createPopup(this.closeBox);
popup.contentSize = new OpenLayers.Size(10, 20);
map.addPopup(popup);
popup.show();
};
marker.events.register("mousedown", feature, markerClick);
markers.addMarker(marker);
}
</script>
And every thing works fine if I remove the map.setCenter(). BUt when I try to use it in my code, my map sudddenly disappears.
I also get the follwoing error in my console window:
Cannot call method 'containsLonLat' of null
I've tried every possible method on this website, but did not reach any where.. What can be the problem?
I think you put an extra Bracket in you code, try map.setCenter(new OpenLayers.LonLat(77, 28), 4); to see if it works or not.
Use leaflet https://leafletjs.com/
var map = L.map('mapid').setView([77.391026, 28.535516], 16);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attributionControl: true
}).addTo(map);
reference: https://leafletjs.com/examples/quick-start/