why map.setCenter is not working? - javascript

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/

Related

Why the information I save in an event is being lost

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 !

OperLayers: display markers while fetching them

I'm fetching via ajax requests a few thousands points to display on an OSM map.
I get 100 points for each call.
I would like them to show up on the map as soon as they are fetched, while now they show up only when all the calls (around 20) are done.
Here is my code:
var source = new ol.source.OSM();
var map_layer = new ol.layer.Tile({
source: source
});
var map_view = new ol.View({
center: ol.proj.fromLonLat([12, 44]),
zoom: 9
});
var map = new ol.Map({
layers: [map_layer, ],
target: 'map-canvas',
view: map_view
});
var target = $(map.getTargetElement());
target.width(window.innerWidth);
target.height(window.innerHeight * 0.9);
map.updateSize();
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(overlay);
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
var markers = new ol.Collection([], {unique: true})
var vectors = new ol.source.Vector({
features: markers
});
var style = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'pin.jpg'
})
});
var layer = new ol.layer.Vector({
source: vectors,
style: style,
});
map.addLayer(layer);
var data = [];
var url = 'some_url';
while (url) {
$.ajax({
async: false,
url: url
}).done(function(data) {
url = data.next;
var res = data.results;
for (var i=0; i<res.length; i++) {
if (res[i].latitude & res[i].longitude) {
var point = ol.proj.fromLonLat([res[i].longitude, res[i].latitude]);
var feature = new ol.Feature({
geometry: new ol.geom.Point(point),
latitude: res[i].latitude,
longitude: res[i].longitude,
})
markers.extend([feature, ]);
}
}
map.render();
});
}
Last instruction you can see (map.render()) shouldn't do the trick? It isn't.
map.renderSync() isn't helping too.
It would be perfect if it could start rendering the map tiles while fetching those points, now even tiles are rendered after fetching is complete.
Looks like the good strategy here is recursion. Simply doing async calls isn't enough.
While each call is async (this letting the map start rendering as soon as possible) the next call is done after showing markers from the previous one.
var url = 'some_url';
var limit = 100;
var offset = 0;
var total_count = 2000;
fetch_data(offset);
function fetch_data(offset) {
$.ajax({
url: encodeURI(url + '?limit=' + limit + '&offset=' + offset)
}).done(function(data) {
var res = data.results;
for (var i=0; i<res.length; i++) {
if (res[i].latitude & res[i].longitude) {
var point = ol.proj.fromLonLat([res[i].longitude, res[i].latitude]);
var feature = new ol.Feature({
geometry: new ol.geom.Point(point),
latitude: res[i].latitude,
longitude: res[i].longitude,
})
markers.extend([feature, ]);
}
}
offset += limit;
if (offset < total_count) {
fetch_data(offset);
}
});
}

How to assign text from object to marker with same index and show relevant text after click to relevant marker? (Openlayers map)

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');
....
};
});

OpenLayer 3 - modify features of Cluster layer

the following question was already raised on "OL3 Dev" but it has been moved to StackOverflow to comply with the group policies.
I've been using OpenLayers 3 for some time and implemented a simple test application where I simulate the movement of several objects on a map.
I use a Vector layer and a corresponding Vector source.
Let's say I have about 1000 features with a ol.geom.Point geometries that are updated every 20-30secs.
I can obtain pretty good results by modifying the geometry coordinates, the result is smooth and works ok.
Now I tried to use the Cluster functionality, to group closed features. Unfortunately in this case the result is very slow and irregular.
I think the problem is due to the change() event being fired every time the geometry of a single feature is changed, so i was wondering:
is there a way to prevent the modification of a feature to be immediately taken into consideration by the Cluster, and fire it only at a specific interval?
Here below you can find two examples, the first without the Cluster source and the second with it.
No Cluster: http://jsfiddle.net/sparezenny/dwLpmqvc/
var mySource = new ol.source.Vector({
features : new Array()
});
var myLayer = new ol.layer.Vector({
source: mySource,
style: function(feature, resolution) {
var myStyle = [new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
})
})];
return myStyle;
}
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
}),
myLayer
],
view: new ol.View({
center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
var positions = new Array();
function Mock(id, longitude, latitude){
this.id=id;
this.latitude=latitude;
this.longitude=longitude;
};
function updatePositions(mocks){
var featuresToBeAdded = new Array();
for (var i=0; i < mocks.length; i++){
var mock = mocks[i];
var id = mock.id;
var previousPosition = positions[id];
var resultFeature;
var position;
// new
if (previousPosition==undefined || previousPosition==null){
position = ol.proj.transform([ mock.longitude, mock.latitude ],
'EPSG:4326', 'EPSG:3857');
positions[id] = mock;
resultFeature = new ol.Feature({
geometry: new ol.geom.Point(position)
});
featuresToBeAdded.push(resultFeature);
}
// update
else{
resultFeature = positions[id].feature;
positions[id] = mock;
position = ol.proj.transform([ mock.longitude, mock.latitude ],
'EPSG:4326', 'EPSG:3857');
resultFeature.getGeometry().setCoordinates(position);
}
positions[id].feature = resultFeature;
}
if (featuresToBeAdded.length>0){
mySource.addFeatures(featuresToBeAdded);
}
//map.render();
}
var myMocks = new Array(1000);
for (var i=0; i<1000; i++){
myMocks[i] = new Mock(i,
37.41+(Math.random()>0.5?0.01:-0.01)*i,
8.82 +(Math.random()>0.5?0.01:-0.01)*i);
}
setInterval(
function(){
var j = Math.round(Math.random()*980);
for (var i=0; i<20; i++){
myMocks[j+i].latitude = myMocks[j+i].latitude + (Math.random()>0.5?0.01:-0.01);
myMocks[j+i].longitude = myMocks[j+i].longitude + (Math.random()>0.5?0.01:-0.01);
}
console.debug("updatePositions..");
updatePositions(myMocks);
}, 5000);
Cluster: http://jsfiddle.net/sparezenny/gh7ox9nj/
var mySource = new ol.source.Vector({
features : new Array()
});
var clusterSource = new ol.source.Cluster({
distance: 10,
source: mySource
});
var myLayer = new ol.layer.Vector({
source: clusterSource,
style: function(feature, resolution) {
var clusteredFeatures = feature.get('features');
var size = feature.get('features').length;
var myStyle = [new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
})];
return myStyle;
}
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
}),
myLayer
],
view: new ol.View({
center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
var positions = new Array();
function Mock(id, longitude, latitude){
this.id=id;
this.latitude=latitude;
this.longitude=longitude;
};
function updatePositions(mocks){
var featuresToBeAdded = new Array();
for (var i=0; i < mocks.length; i++){
var mock = mocks[i];
var id = mock.id;
var previousPosition = positions[id];
var resultFeature;
var position;
// new
if (previousPosition==undefined || previousPosition==null){
position = ol.proj.transform([ mock.longitude, mock.latitude ],
'EPSG:4326', 'EPSG:3857');
positions[id] = mock;
resultFeature = new ol.Feature({
geometry: new ol.geom.Point(position)
});
featuresToBeAdded.push(resultFeature);
}
// update
else{
resultFeature = positions[id].feature;
positions[id] = mock;
position = ol.proj.transform([ mock.longitude, mock.latitude ],
'EPSG:4326', 'EPSG:3857');
resultFeature.getGeometry().setCoordinates(position);
}
positions[id].feature = resultFeature;
}
if (featuresToBeAdded.length>0){
mySource.addFeatures(featuresToBeAdded);
}
//map.render();
}
var myMocks = new Array(1000);
for (var i=0; i<1000; i++){
myMocks[i] = new Mock(i,
37.41+(Math.random()>0.5?0.01:-0.01)*i,
8.82 +(Math.random()>0.5?0.01:-0.01)*i);
}
setInterval(
function(){
var j = Math.round(Math.random()*980);
for (var i=0; i<20; i++){
myMocks[j+i].latitude = myMocks[j+i].latitude + (Math.random()>0.5?Math.random()*0.01:-Math.random()*0.01);
myMocks[j+i].longitude = myMocks[j+i].longitude + (Math.random()>0.5?Math.random()*0.01:-Math.random()*0.01);
}
console.debug("updatePositions..");
updatePositions(myMocks);
}, 5000);
As you can see I have 1000 features and I try to update the positions of 20 of them every 5 seconds.
In the first case the interaction with the map is smooth, whilst in the second case it often stops or slow down.
Any clue or advise about how to avoid that?
Thanks in advance
This is an old link now, but as I've encountered exactly the same issue, I thought I'd post my work-around.
The idea is to cripple the offending event handler in the cluster source, and only fire that same code every frame render.
Note that the code as presented:
Is really quite a hack, as it's messing about with private functions.
Because of the above, it may well need modifying for different non-debug builds.
Uses a newer version of OL3 than the OP (see also point 2!).
JSFiddle here
if (ol.source.Cluster.prototype.onSourceChange_)
{
// Make a new pointer to the old sourceChange function.
ol.source.Cluster.prototype.newSourceChange =
ol.source.Cluster.prototype.onSourceChange_;
// Nuke the old function reference.
ol.source.Cluster.prototype.onSourceChange_ = function() {};
}
if (ol.source.Cluster.prototype.Ra)
{
// As above, but for non-debug code.
ol.source.Cluster.prototype.newSourceChange =
ol.source.Cluster.prototype.Ra;
ol.source.Cluster.prototype.Ra = function() {};
}
// Later on..
map.on('postrender', clusterSource.newSourceChange, clusterSource);
As you can see, this comfortably handles the 1000 features even with a 100ms update time.

OpenLayers => feature is null

This is my GeoJSON result. PasteBin
But when I load it, the result I get in firebug is feature is null. Why's that, are there any errors in my result? The coords in the JSON is written in projection WGS84, and in the code I also have set the externalProjection as WGS84. So why do I get the return "feature is null"?
The code I use to manage my map is :
$(document).ready(function() {
var wgs84 = new OpenLayers.Projection('EPSG:4326');
var layer = null;
var map = new OpenLayers.Map('map',{projection: wgs84});
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
var baseProjection = layer.projection;
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(10,10), 4);
map.events.register("moveend", null, function(){
if(map.zoom == 10)
{
var bounds = map.getExtent();
console.log(bounds);
var ne = new OpenLayers.LonLat(bounds.right,bounds.top).transform(map.getProjectionObject(),wgs84);
var sw = new OpenLayers.LonLat(bounds.left,bounds.bottom).transform(map.getProjectionObject(),wgs84);
var vectorLayer = new OpenLayers.Layer.Vector();
map.addLayer(vectorLayer);
$.getJSON('ajax.php?a=markers&type=json&sw=('+sw.lon+','+sw.lat+')&ne=('+ne.lon+','+ne.lat+')',function(data){
//$.getJSON('test.json',function(data){
var geojson_format = new OpenLayers.Format.GeoJSON({
'externalProjection': wgs84,
'internalProjection': baseProjection
});
vectorLayer.addFeatures(geojson_format.read(data));
});
}
});
});
Your sample OpenLayer code is working correctly, the problem is in your GeoJSON: you misspelled coordinates as "coordninates"

Categories

Resources