Why is my openlayers map disappearing when I add an extent constraint? - javascript

I am new to openlayers, and have tried to teach myself what I can through the tutorials.
My map works fine until I add an extent to the view. As soon as I do that, the map disappears. (zoom controls remain).
I have searched the documentation for help with this but no luck.
Here is my code:
<div id="map" class="map"></div>
<script type="text/javascript">
const extentNESW = [ 4422340.708467, -10578604.167351, 3169996.437043, -9735019.922400 ]
const extentWSEN = [-9735019.922400, 3169996.437043, -10578604.167351, 4422340.708467 ]
const centerLonLat = [ -10160621.295892, 3903791.908581 ]
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: (centerLonLat),
zoom: 10,
extent: extentWSEN,
})
});
</script>
If i remove the line with extent, the map works again. What gives?

It seems that your extent array has wrong order of coordinates. The order has to be:
[minX, minY, maxX, maxY]
More specifically, in your case, you have swapped minX and maxX. Replace your array with the following:
const extentWSEN = [-10578604.167351, 3169996.437043, -9735019.922400, 4422340.708467 ];

Related

Image is displayed wrong on static image layer on top of osf layer

I followed the example from the openlayers book to add a static image on top of an osf layer. It works, but my image (256x256) is displayed as a rectangle. I tried around with the coordinates for the projection and checked out other posts here on, but I can't get my head around it why the image is not displayed as a square:
// Create map
var map = new ol.Map({
target: 'map', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
layers: [
// Add a new Tile layer getting tiles from OpenStreetMap source
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([16.3725, 48.208889], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
// Create an image layer
var imageLayer = new ol.layer.Image({
opacity: 0.75,
source: new ol.source.ImageStatic({
attributions: [
new ol.Attribution({
html: ''
})
],
url: 'https://placebear.com/256/256',
imageSize: [256, 256],
projection: map.getView().getProjection(),
imageExtent: ol.extent.applyTransform(
[0, 0, 16.3725, 48.208889], ol.proj.getTransform("EPSG:4326", "EPSG:3857"))
})
});
map.addLayer(imageLayer);
ol.source.ImageStatic was made to put a georeferenced image (e.g. a scan of a historic map) on a map. Is this what you have in mind? If you just want to display an image and anchor it to a location on the map, you'd better use ol.Overlay or an ol.layer.Vector with a feature with an ol.style.Icon.
That said, your image will only be displayed as square if the imageExtent set on your ol.source.ImageStatic results in a square on the projected map view.

OpenLayers 3.13: issue with bindTo by linking two views

I'm new in using OpenLayers. I'm trying to do some exercises with version 3.0 and 3.13.
I have to link two views: the second map respond to changes in the first map, but zoomed out three times; when the first map is panned or zoomed, the second map should center on the same location and stay zoomed out in three levels.
I'm using the following code that works quite well on version 3.0, but not on v3.13: the console prints Uncaught TypeError: view2.bindTo is not a function.
In another example I use map2.bindTo('view', map); on v3.13, without any issue. What is the difference?
EDIT
I'm wrong, I obtain the same issue.
There is no bindTo anymore (see the comment by Jonatas Walker for details).
var layer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var london = ol.proj.transform([-0.12755, 51.507222], 'EPSG:4326', 'EPSG:3857');
var view = new ol.View({
center: london,
zoom: 6,
});
var view2 = new ol.View({
center: london,
zoom: 3,
});
var map = new ol.Map({
target: 'map1',
layers: [layer],
view: view,
//renderer: 'dom'
});
var map2 = new ol.Map({
target: 'map2',
layers: [layer],
controls: new ol.Collection(),
interactions: new ol.Collection(),
view: view2
});
view2.bindTo('center', view);
view.on('change:resolution', function(){
var zoom = this.getZoom();
if (zoom >= 3 && zoom <= 18)
view2.setZoom(this.getZoom()-3);
else view2.setZoom(this.getZoom());
});
Since PR #3472 there's no bindTo method and you can achieve this center binding with something like:
view.on('change:center', function(evt){
view2.setCenter(view.getCenter());
});

How to easily create a heatmap layer from a pre-existing vector layer of points in OpenLayers 3?

Like the title said I have a vector of points on a OpenLayers map that I need to turn into a heatmap. I already have this code below (which works just fine for me) but I need to add thousands of more points(in a different data file) and be able to visualize it with a density/heatmap. Its current state is a simple open street map with one layer of locations plotted on a world map! I would post an image but reputation rules...
<!DOCTYPE HTML>
<html>
<head>
<title>AIS Map Template</title>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
function init() {
map = new OpenLayers.Map("mapdiv");
var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);
// ADD POINTS TO A LAYER
var pois = new OpenLayers.Layer.Vector("Ships",
{
projection: new OpenLayers.Projection("EPSG:4326"),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "./AISdecoded.txt",
format: new OpenLayers.Format.Text(
{
extractStyles: true,
extractAttributes: true
})
})
});
// ADD POINTS LAYER TO MAP
map.addLayer(pois);
var layer_switcher= new OpenLayers.Control.LayerSwitcher({});
map.addControl(layer_switcher);
var lonlat = new OpenLayers.LonLat(0,0).transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator
);
var zoom = 1;
map.setCenter(lonlat, zoom);
}
</script>
<style>
#mapdiv { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>
</head>
<body onload="init();">
<p>AIS Map Data</p>
<div id="mapdiv"></div>
</body>
</html>
The testing data looks like this:
lat lon title description icon iconSize iconOffset
49.4756 0.13138 227006760 Navigation Status: 0 ship_sea_ocean.png 16,16 -8,-8
51.2377 4.41944 205448890 Navigation Status: 0 ship_sea_ocean.png 16,16 -8,-8
I have tried various methods to try and get a heatmap produced but unfortunaetly I'm a little lacking on the Javascript/HTML side of things. I have looked at the examples online including the earthquake example provided by OpenLayers but 99% of them deal with KML files and since I need this application to run offline on a localhost server I cannot do it that way.
I have attempted this without success, among other flailing:
var heatmapLayer = new ol.layer.Heatmap({
source: new OpenLayers.Layer.Vector("Ships",
{
projection: new OpenLayers.Projection("EPSG:4326"),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "./AISdecoded.txt",
format: new OpenLayers.Format.Text(
{
extractStyles: true,
extractAttributes: true
})
})
}),
opacity: 0.9
});
// Create a tile layer from OSM
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
// Create the map with the previous layers
var map = new ol.Map({
target: 'map', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
layers: [osmLayer, heatmapLayer],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
I have a feeling this is much easier than I think it is but I have been trying to do this for about a week now and my patience is nearing its end. If you know how to do this specifically that's awesome! But if you don't, can you push me in the right direction? Any help is much appreciated, thanks!
EDIT
OK so I edited the code a bit to be fully OL3 and use a geoJSON approach. It now looks like this:
<!DOCTYPE HTML>
<html>
<head>
<title>AIS Map Template</title>
<script src="http://openlayers.org/en/v3.5.0/build/ol.js" type="text/javascript"></script>
<link rel='stylesheet' href='http://ol3js.org/en/master/css/ol.css'>
<script>
function init() {
var vector = new ol.layer.Heatmap({
source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
}),
opacity: .9
});
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
// Create the map with the previous layers
var map = new ol.Map({
target: 'map', // The DOM element that will contain the map
renderer: 'canvas', // Force the renderer to be used
layers: [osmLayer,vector],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
}
</script>
<style>
#map { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>
</head>
<body onload="init();">
<p>AIS Map Data</p>
<div id="map"></div>
</body>
</html>
But it's still not working, only a map, no layer. This is the way I found how to do via examples like this one. Firebug is saying "TypeError: ol.source.GeoJSON is not a constructor" but I don't know how to do this any other way. pls halp, thanks!
Change this:
var vector = new ol.layer.Heatmap({
source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
}),
to:
var vector = new ol.layer.Heatmap({
source: new ol.source.Vector({
url: './AISdecoded.geojson',
projection: 'EPSG:3857',
format: new ol.format.GeoJSON()
}),

Open Layer 3 blank fields when dragging map, how to restrict it

I don't want that the users see the blank field when dragging the map. I want restrict it. I didn't find any great resolution.
my map code:
var map = new ol.Map({
layers: [new ol.layer.Tile({
source: new ol.source.MapQuest({ layer: 'osm' }) }), vectorLayer],
target: document.getElementById('map'),
controls: ol.control.defaults().extend([
new ol.control.ScaleLine(),
new ol.control.ZoomSlider()
]),
view: new ol.View({
center: [-6217890.205764902, -1910870.6048274133],
zoom: 3,
maxZoom: 20
})
});
Problem:
There are a couple of things that you could do:
Set a background color or image on your map container like in the examples to make the white gaps look nicer.
.map {
...
background: url(map-background.jpg) repeat;
}
Set the minZoom property on the view to prevent the map from being zoomed out too far. But on large screens users might still see gaps.
view: new ol.View({
...
minZoom: 4
})
Or restrict the view extent to the tile boundaries (ol.proj.get('EPSG:3857').getExtent()). This is not yet included in OpenLayers, but you'll find a work-around in this question.

Openlayers3 with custom tile server

I've got a problem with the latest openlayers3 beta. I'm trying to use custom tile server using xyz layer. The thing is the tiles are re not rendered for some reason. Using firebug I can see that the tile requests are send and the images are fetched succesfuly, though they do not show up...
Everything works in chrome however.
var baseLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://xx.xx.xx.xx:33333/osm/{z}/{x}/{y}.png'
})
});
var map = new ol.Map({
controls: ol.control.defaults().extend([
]),
target: 'map',
layers: [baseLayer],
view: new ol.View2D({
center: ol.proj.transform([21.999529, 50.041682], 'EPSG:4326', 'EPSG:3857'),
zoom: 13
})
});
Can you try putting a minus before your tile url's y value?
var baseLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://xx.xx.xx.xx:33333/osm/{z}/{x}/{-y}.png'
})
});
EDIT: Wow... Super old question... My bad, but maybe someone can use this answer anyway....

Categories

Resources