How to store map tiles locally using openlayers - javascript

I just picked up a piece of code from the openlayers3 examples see HERE, now everytime you click the "geolocate me" button the tiles of the map are reloaded , now is there anyway for the tiles of the map to be stored locally ? I.E. when i click on the "geolocate me!" button the 2nd time around the tiles should be loaded from the users browser locally, rather than being fetched from the internet.
The code for generating the map is as following:
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: view
});
I tried the following using localstorage:
if(localStorage.layer) {
localStorage.setItem('layer' , JSON.stringify(new ol.layer.Tile({ source: new ol.source.OSM()}) )); console.log(localStorage.layer);
}
var map = new ol.Map({
layers: localStorage.layer ? [JSON.parse(localStorage.getItem('layer'))] : [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: * #type {olx.control.AttributionOptions} ({
collapsible: false
})
}),
view: view
});
But this does't seem to work, what can i do so that the tiles of the map are stored locally instead of being loaded from over the internet ?
a example i have seen using the DOJO library is HERE.

Related

"map.once is not a function error" trying to duplicate OpenLayers example

I am trying to duplicate this OpenLayers 6 example
https://openlayers.org/en/latest/examples/export-map.html
It is to a javascript to download your OpenLayers 6 map
I am using different configuration and haven't been able to get it to work
http://australiamap.ca/export-map/
I get a "map.once is not a function error"
Here is your code (i truncated some part for readability)
window.onload = init;
function init(){
const torontoCenterCoordinate = [-8850000, 5410000]
const map = new ol.Map({
view: new ol.View({
center: torontoCenterCoordinate,
zoom: 10
}),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map'
})
}
function init2(){
...
}
document.getElementById('export-png').addEventListener('click', function () {
map.once('rendercomplete', function () {
...
});
map.renderSync();
});
You are trying to access variable map which is declare inside function init inside event listener of click. That's possible due to how scope work in JavaScript.
There is a coincidence that map actually resolve to a DOM element (in modern browser if you have an HTML element with id map then browser will save that element into variable map for you)
To fix your problem, you can either:
Move move to global scope so event listener can access it
// outside of init
const map = new ol.Map({
view: new ol.View({
center: torontoCenterCoordinate,
zoom: 10
}),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map'
})
Move even listener inside init
function init(){
const torontoCenterCoordinate = [-8850000, 5410000]
const map = new ol.Map({
view: new ol.View({
center: torontoCenterCoordinate,
zoom: 10
}),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map'
})
document.getElementById('export-png').addEventListener('click', function () {
map.once('rendercomplete', function () {
...
});
map.renderSync();
});
}

"SecurityError: This operation is insecure" when calling domtoimage.toPng() in OpenLayers example

I am currently working on adding functionality to convert an OpenLayers Map into a png file (The example is here). However, when calling domtoimage.toPng() in the below code, Firefox (Ubuntu version 68.0.2) gives me the error SecurityError: This operation is insecure. I have checked all around and no one else seems to be having this problem with the dom-to-image library, and so I am stuck on how to fix this error. My JavaScript code for the Map is very similar to the code given in the example and is given here:
<script type="text/javascript">
var extent = [0, 0, 3000, 4213];
var projection = new ol.proj.Projection({
code: 'my-image',
units: 'pixels',
extent: extent,
});
var map = new ol.Map({
controls: ol.control.defaults().extend([
new ol.control.FullScreen()
]),
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
attributions: 'My Image Attributions',
url: "{{record | img_url}}", // Django stuff defined earlier
projection: projection,
imageExtent: extent
})
})
],
target: 'map',
view: new ol.View({
projection: projection,
center: ol.extent.getCenter(extent),
zoom: 2,
maxZoom: 8
})
});
map.addOverlay(new ol.Overlay({
position: [0, 0],
element: document.getElementById('null')
}));
// export options for dom-to-image.
var exportOptions = {
filter: function(element) {
return element.className ? element.className.indexOf('ol-control') === -1 : true;
}
};
document.getElementById('export-png').addEventListener('click', function() {
map.once('rendercomplete', function() {
domtoimage.toPng(map.getTargetElement(), exportOptions)
.then(function(dataURL) {
var link = document.getElementById('image-download');
link.href = dataURL;
link.click();
});
});
map.renderSync();
});
The HTML is effectively the same as in the example and so I believe the problem lies somewhere in here. Perhaps it is something with using a StaticImage in the Map? Or maybe going through the Django framework tampers with it in some unknown way? I am not entirely sure, and any diagnosis/help with fixing this issue would be much appreciated.
I think there should be something like:
new ol.layer.Tile({
name: 'name',
source: new ol.source.TileWMS({
...
crossOrigin: 'anonymous' // <-- Add this to the json.
})
})
Read more:
https://openlayers.org/en/v4.6.5/apidoc/ol.source.ImageWMS.html
https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

Getting typeError after adding layer to map

I go tthis type of error:
"Cannot read property 'closure_uid_521373967' of null".
This occures after i make source that contain no features yet.
var vectorSource = new ol.source.Vector({
});
after that i make a Layer
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
and then i init the map:
var map = new ol.Map({
layers: [new ol.layer.Tile({ source: new ol.source.OSM({url:"http://tile.openstreetmap.org/{z}/{x}/{y}.png"}) }), vectorLayer],
target: document.getElementById('map'),
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
its seems to work fine in my home when it is simple as here , but when i try to make it work in my job , that the scanario is kind a bit more complicated , i lack that type of error that i mention before.
Please view this Snippet.
It is a good idea to separate layer definition from map instantiation. The latter makes things very convenient, but it makes things difficult for debugging.
With that in mind, I defined an OSM Layer and your Vector layer and added both to a map.
You don't need to use getElementById. You can simply supply the id of the div as the target of the map.
I'm not able to replicate your TypeError. My suspicion is that it came from the addition of the unnecessary getElementById, though.
Can you post a link to the code that's not working?
// layers
var vectorSource = new ol.source.Vector({
});
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: vectorSource,
})
});
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map = new ol.Map({
layers: [osmLayer, vectorLayer],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 3
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script>
<body>
<div id='map'>
</div>
</body>

Pass object arrays to template

I will try rephrase mine question from this post.
I'm using openlayers3 to display random building markers on the map. You can see it in this JSFIDDLE example.
This is the code for the map
/* Create the map */
// setting up coordinates for map to display
var city = ol.proj.transform([-73.920935,40.780229], 'EPSG:4326', 'EPSG:3857');
// setting up openlayer3 view
var view = new ol.View({
center: city,
zoom: 13
});
// Create the map
var map = new ol.Map({
target: 'map',
renderer: 'canvas',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: view
});
// Setup markers
var markers = new ol.layer.Vector({
tittle: 'City Apratments',
source: new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.927870, 40.763633])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.917356, 40.763958])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.915530, 40.779665])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.916045, 40.779372])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.919682, 40.777365])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.908980, 40.776013])),
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-73.917356, 40.763958])),
})
]
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixel',
opacity: 0.75,
src: 'http://openlayers.org/en/v3.12.1/examples/data/icon.png',
})
})
});
map.addLayer(markers);
I need to display some data about the building (street address, picture of building, more info, etc, something like you can see when you interact whit the google map, when you click on the map and you trigger off canvas menu whit some info about that place), so when you interact and click on the marker template will bi rendered and on it you will see all the data for that object, I need to be able to display different data for different marker building.
QUESTION:
You can see mine markers are displayed trough openlayer3 source.Vector, how can I pass this array of objects to django-view then django-template from this javascript code, how is this possible?
I want to avoid django-orm and do this from js --> django-view --> django-template.
I goal is to render a template when you click on the marker, so you can see some data about the building, furthermore I want to change this template whenever I want.
I would like to understand how can I do this, can someone help, thank you.

OpenLayers 3.6.0 TouchEvents

I can't seem to add event listeners for touch events. Only moveend gets fired.
map.on('zoomend', mapEvent);
map.on('moveend', mapEvent);
map.on('touchmove', mapEvent);
map.on('touchstart', mapEvent);
None of these work
map = new ol.Map({
eventListeners: {
"zoomend": mapEvent,
"changelayer": mapEvent,
"changebaselayer": mapEvent,
"mousedown": mapEvent,
"touchmove": mapEvent
},
And this causing an error - "Uncaught TypeError: Cannot read property 'register' of undefined"
map.events.register('touchmove', map, function(e) {
console.log("touchmove")
});
map.events.register('touchend', map, function(e) {
console.log("touchend")
});
So now I'm totally lost!?
That is exactly what is supposed to happen!
All those events you listed, besides moveend, don't exist on OpenLayers 3.6.0 anymore. Also, the config option eventListeners under ol.Map doesn't exist.
You can check all events and config options for ol.Map on the official API docs. The events are listed on Fires section.
Additionally, check this JSFiddle for some other events (pointermove, pointerdrag). On Chrome, you can also use Developer Tools (F12) to emulate a touch device and see what happens.
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
map.on('moveend', function(e) {
console.log("moveend")
});
map.on('pointermove', function(e) {
console.log("pointermove")
});
map.on('pointerdrag', function(e) {
console.log("pointerdrag")
});

Categories

Resources