I am trying to load a layer on the OSM map using OL. The service which I have requires the authentication header, I have written the code but somehow it's not working. Here is my code
function customLoader(tile, src) {
var client = new XMLHttpRequest();
client.open('GET', src);
client.setRequestHeader("Ocp-Apim-Subscription-Key","XXXXXXXXXXXXXX");
client.onload = function() {
tile.getImage().src = src;
};
client.send();
}
var layers = [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Tile({
extent: [-425988.3826589292,6390953.66876267,161047.99457094132,6677439.650775372],
source: new ol.source.TileWMS({
url: 'https://url.com/WMSServer',
tileLoadFunction: customLoader,
params: {'LAYERS': '21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0', 'TILED': true},
serverType: 'WMSServer',
transition: 0
})
})
];
var map = new ol.Map({
layers: layers,
target: 'map',
view: new ol.View({
center: [-4.095013, 56.550473],
zoom: 4
})
});
I am not sure what I am doing wrong.
I cannot get the base64 method to work either. It would be better to use the object url method from https://openlayers.org/en/latest/apidoc/module-ol_Tile.html#~LoadFunction (but note that object urls can cause memory leaks if not revoked)
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.4.3/css/ol.css" type="text/css">
<style>
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.4.3/build/ol.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: 'https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png',
maxZoom: 17,
tileLoadFunction: function (tile, src) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.addEventListener('load', function (evt) {
var data = this.response;
if (data !== undefined) {
var url = URL.createObjectURL(data);
tile.getImage().addEventListener('load', function () {
URL.revokeObjectURL(url);
});
tile.getImage().src = url;
} else {
tile.setState(3);
}
});
xhr.addEventListener('error', function () {
tile.setState(3);
});
xhr.open('GET', src);
xhr.send();
}
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
</script>
</body>
</html>
Related
I have a model (from another php class. I used a include sentence) with information in order to be shown on openstreet map as points. My code works fine but if I try to separate the code using a function, it doesnt work. My code, including the function is:
echo '
<html>
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css">
</head>
<body>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"> </script>
<div id="map" class="map"></div>
<script>
//I CREATE THE MAP
var attribution = new ol.control.Attribution({
collapsible: true
});
var map = new ol.Map({
controls: ol.control.defaults({attribution: false}).extend([attribution]),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
maxZoom: 18
})
})
],
target: "map",
view: new ol.View({';
echo " center: ol.proj.fromLonLat([$longitud, $latitud]),
maxZoom: 18,
zoom: $zoom
})
});
";
// I READ THE MODEL GETTING LONGITUDE AND LATITUDE OF EACH POINT
$i;
if ($modeloDatos!=null) {
for($i=0;$i<sizeof($modeloDatos);$i++){
$modeloImprimir = $modeloDatos[$i];
$long=$modeloImprimir->getLongitud();
$lat=$modeloImprimir->getLatitud();
showCentro($long,$lat); //I CALL TH FUNCTION
}
}
echo "
</script>
</body>
</html>";
function showCentro($longi, $lati) { //I RECEIVE THE COORDNATES AND DRAW A FILLED POINT
echo "
map.addLayer(
new ol.layer.Vector({
source: new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([$longi,$lati]))})
]
}),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({ ";
echo'
color: "red"
})
})
})
});
);';
}
I would like to draw each point from the model separating the code and using a function in order to clarify the program.
I have a problem in my open layer (6.1.) project with a popup bubble.
I am not able to create and see the popup and fill it, not even with a single GeoJSON layer with cities.
I read this without progress:
popup with multiple points features
I would like just render the name of the city when clicking on the icon.
Index.html
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="icon" href="pic/fav.png" sizes="192x192" />
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<title>Retail Space</title>
</head>
<!--++++++++++++++++++++++++++++++++++++++ BODY +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
<body>
<div id="container">
<!--++++++++++++++++++++++++++++++++++++++ HEADERBAR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
<div id="headerbar">
<div id="logobar">
</div>
<div id="controlbar">
</div>
</div>
<!--++++++++++++++++++++++++++++++++++++++ MAPBAR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>
<div id="map-container" ><div id="popup"></div>
<div id="tooltip" class="tooltip"></div>
</div>
<script src="main.js"></script>
</div> <!--/container-->
</body>
</html>
main.js
import GeoJSON from 'ol/format/GeoJSON';
import TileJSON from 'ol/source/TileJSON';
import Map from 'ol/Map';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import TileLayer from 'ol/layer/Tile';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import OSM from 'ol/source/OSM';
import TileWMS from 'ol/source/TileWMS';
import Overlay from 'ol/Overlay';
import {Style, Fill, Stroke, Icon} from 'ol/style';
import {fromLonLat} from 'ol/proj';
import sync from 'ol-hashed';
var iconStyle_municip = new Style({
image: new Icon({
anchor: [0.5, 5],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'pic/municip.png'
})
});
//OSM layer creation
var OSMmap = new TileLayer({
source: new OSM(),
format: new GeoJSON({featureProjection: 'EPSG:3857'}),
});
//Obce 5000+ layer creation
var cities = new VectorLayer({
source: new VectorSource({
format: new GeoJSON({featureProjection: 'EPSG:3857'}),
url: 'obce5000geojson.geojson'
})
});
cities.setStyle(iconStyle_municip);
//Map initiation
new Map({
target: 'map-container',
layers: [OSMmap, cities],
view: new View({
center: fromLonLat([15, 49.80]),
zoom: 8
}),
});
//tooltip start
var element = document.getElementById('popup');
var popup = new Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -50]
});
map.addOverlay(popup);
// display popup on click
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature) {
return feature;
}
);
if (feature) {
var coordinates = this.getCoordinateFromPixel(evt.pixel);
popup.setPosition(coordinates);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.get('obec')
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
Main problem is you aren't retaining a reference to your map variable.
//Map initiation
new Map({
target: 'map-container',
layers: [OSMmap, cities],
view: new View({
center: fromLonLat([15, 49.80]),
zoom: 8
}),
});
That fails when the code tries to use it:
map.addOverlay(popup);
Keep a reference to the map:
//Map initiation
var map = new Map({
target: 'map-container',
layers: [OSMmap, cities],
view: new View({
center: fromLonLat([15, 49.80]),
zoom: 8
}),
});
proof of concept fiddle
code snippet:
var iconStyle_municip = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 5],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'https://openlayers.org/en/v4.6.5/examples/data/icon.png'
})
});
//OSM layer creation
var OSMmap = new ol.layer.Tile({ // TileLayer({
source: new ol.source.OSM(),
format: new ol.format.GeoJSON({featureProjection: 'EPSG:3857'}),
});
//Obce 5000+ layer creation
var cities = new ol.layer.Vector({ // VectorLayer({
source: new ol.source.Vector({ // VectorSource({
format: new ol.format.GeoJSON({featureProjection: 'EPSG:3857'}),
url: 'https://api.myjson.com/bins/upiqa'
})
});
cities.setStyle(iconStyle_municip);
//Map initiation
var map = new ol.Map({
target: 'map-container',
layers: [OSMmap, cities],
view: new ol.View({
center: ol.proj.fromLonLat([15, 0]),
zoom: 2
}),
});
//tooltip start
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -10]
});
map.addOverlay(popup);
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature) {
return feature;
}
);
if (feature) {
var coordinates = this.getCoordinateFromPixel(evt.pixel);
popup.setPosition(coordinates);
$(element).popover({
'placement': 'top',
'html': true,
'content': "test content" // feature.get('obec')
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map-container {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#popup {
background: #FFFFFF;
border: black 1px solid;
}
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.1.1/build/ol.js"></script>
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<div id="map-container" class="map"></div>
<script src="https://cdn.jsdelivr.net/npm/jquery-popover#0.0.4/src/jquery-popover.min.js"></script>
<div id="popup">
<b>test</b>
</div>
I am unable to load ol3cesium map in Ionic 2.
My index.html (code within body tag):
<ion-app></ion-app>
<script src="http://openlayers.org/en/v3.16.0/build/ol.js"
<script src="../ol3-cesium-v1.17/ol3cesium.js"></script>
<script src="../ol3-cesium-v1.17/Cesium/Cesium.js"></script>
My home.ts:
Inside constructor, below code is added --
var view = new ol.View({
projection: 'EPSG:4326',
center: [-100, 35],
zoom: 3
});
var layer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {
'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
}
})
});
var overlay = new ol.layer.Tile({
opacity: 0.7,
extent: [-124.74, 24.96, -66.96, 49.38],
source: new ol.source.TileWMS(/** #type {olx.source.TileWMSOptions} */({
url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: { 'LAYERS': 'topp:states', 'TILED': true },
serverType: 'geoserver',
crossOrigin: 'anonymous'
}))
});
var ol2d = new ol.Map({
layers: [layer, overlay],
target: 'map2d',
view: view
});
var ol3d = new olcs.OLCesium({ map: ol2d });
var scene = ol3d.getCesiumScene();
var terrainProvider = new Cesium.CesiumTerrainProvider({
url: '//assets.agi.com/stk-terrain/world'
});
ol3d.getCesiumScene().scene.terrainProvider = terrainProvider;
ol3d.setEnabled(true);
});
'map2d' is my div id in home.html.
I don't know why it is saying 'olcs is not defined' when running the project by ionic serve --lab. How can I resolve this JavaScript issue?
i solved it.
Actually i had to put cesium.js and ol3cesium inside www folder.
I'm trying to force a vector layer in OpenLayers 3 to periodically reload its data from a GeoJSON source. The GeoJSON source changes from time to time.
After many different attempts using different methods, I think this is the closest I've managed to get so far:
$(document).ready(function(){
map.once("postcompose", function(){
//start refreshing each 3 seconds
window.setInterval(function(){
var source = testLayer.getSource();
var params = source.getParams();
params.t = new Date().getMilliseconds();
source.updateParams(params);
}, 3000);
});
});
However this is giving me the following (every 3 seconds of course):
Uncaught TypeError: source.getParams is not a function
Here's all of the other code I'm using to load and display the GeoJSON file. The other layers in the map are loaded in the same way:
var testSource = new ol.source.Vector({
url: '/js/geojson/testfile.geojson',
format: new ol.format.GeoJSON()
});
...
window.testLayer = new ol.layer.Vector({
source: testSource,
style: function(feature, resolution) {
var style = new ol.style.Style({
fill: new ol.style.Fill({color: '#ffffff'}),
stroke: new ol.style.Stroke({color: 'black', width: 1}),
text: new ol.style.Text({
font: '12px Verdana',
text: feature.get('testvalue'),
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.1)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 1)',
width: 1
})
})
});
return style
}
});
...
var olMapDiv = document.getElementById('olmap');
var map = new ol.Map({
layers: [paddocksLayer,zonesLayer,structuresLayer,roadsLayer,testLayer],
interactions: ol.interaction.defaults({
altShiftDragRotate: false,
dragPan: false,
rotate: false
}).extend([new ol.interaction.DragPan({kinetic: null})]),
target: olMapDiv,
view: view
});
view.setZoom(1);
view.setCenter([0,0]);
I read somewhere else that getParams simply doesn't work on vector layers, so this error wasn't entirely unexpected.
Is there an alternative method which will reload (not just re-render) a vector layer?
Thanks in advance. I must also apologise in advance as I'll need really specific guidance with this - I'm very new to JS and OpenLayers.
Gareth
(fiddle)
You can achieve this with a custom AJAX loader (when you pass url to ol.source.Vector this is AJAX as well). Then you can reload your JSON file as you will.
You can use any AJAX library you want but this is as simple as:
var utils = {
refreshGeoJson: function(url, source) {
this.getJson(url).when({
ready: function(response) {
var format = new ol.format.GeoJSON();
var features = format.readFeatures(response, {
featureProjection: 'EPSG:3857'
});
source.addFeatures(features);
source.refresh();
}
});
},
getJson: function(url) {
var xhr = new XMLHttpRequest(),
when = {},
onload = function() {
if (xhr.status === 200) {
when.ready.call(undefined, JSON.parse(xhr.response));
}
},
onerror = function() {
console.info('Cannot XHR ' + JSON.stringify(url));
};
xhr.open('GET', url, true);
xhr.setRequestHeader('Accept','application/json');
xhr.onload = onload;
xhr.onerror = onerror;
xhr.send(null);
return {
when: function(obj) { when.ready = obj.ready; }
};
}
};
I'm trying to make a Polymer module for working with OpenLayers 3 and displaying openstreetmaps. I know there is a great module working with leaflet but I need some specifics functions like map orientation.
Anyway, I code something and it's working except one thing I can't figure out : When the page loads, only the commands are showing (Zoom + / Zoom -) and not the map (and not any thing such as marker, etc). But if I resize my window (my Chrome window I mean) the map appear and all is working fine !! I was thinking maybe something in relation with DOM Loading...
Module code :
<dom-module id="openlayer-map">
<link rel="stylesheet" href="http://openlayers.org/en/v3.7.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.7.0/build/ol.js" type="text/javascript"></script>
<style>
:host {
display: block;
}
#map
{
position: absolute;
height: 100%;
}
</style>
<template>
<div id="map" class="map"></div>
<!-- Tests
<input is="iron-input" bind-value="{{latitude}}" placeholder="latitude">
<input is="iron-input" bind-value="{{longitude}}" placeholder="longitude">
-->
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'openlayer-map',
properties:
{
currentCenter: Array,
currentView: ol.View,
olmap: ol.Map,
geolocation: ol.Geolocation,
layer: Object,
longitude:
{
type: Number,
value:12.889101100000062,
notify: true,
observer: '_updateLongitude'
},
latitude:
{
type: Number,
value: 15.7622695,
notify: true,
observer: '_updateLatitude'
},
geotracking:
{
value: false,
type: Boolean,
notify: true,
},
elemReady: Boolean,
},
ready: function()
{
console.log('openlayer-map ready');
this.initialConfig();
this.elemReady = true;
this.setCenter(this.latitude,this.longitude);
},
initialConfig: function()
{
console.log('initial config for the map...');
this.currentView = new ol.View({
zoom: 14
});
var source = new ol.source.OSM();
this.layer = new ol.layer.Tile();
this.layer.setSource(source);
this.olmap = new ol.Map({
layers: [this.layer],
target: this.$.map,
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: this.currentView
});
// Localisation
this.geolocation = new ol.Geolocation({
projection: this.currentView.getProjection()
});
this.geolocation.setTracking(this.geotracking);
if(this.geolocation)
{
var accuracyFeature = new ol.Feature();
this.geolocation.on('change:accuracyGeometry', function() {
accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
}.bind(this));
var positionFeature = new ol.Feature();
positionFeature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#3399CC'
}),
stroke: new ol.style.Stroke({
color: '#fff',
width: 2
})
})
}));
this.geolocation.on('change:position', function() {
var coordinates = this.geolocation.getPosition();
positionFeature.setGeometry(coordinates ?
new ol.geom.Point(coordinates) : null);
}.bind(this));
var featuresOverlay = new ol.layer.Vector({
map: this.olmap,
source: new ol.source.Vector({
features: [accuracyFeature, positionFeature]
})
});
}
},
_updateLatitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update latitude from '+oldValue+' to '+newValue);
this.setCenter(newValue, this.longitude);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
_updateLongitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update longitude from '+oldValue+' to '+newValue);
this.setCenter(this.latitude, newValue);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
setCenter: function(latitude, longitude)
{
var center = [longitude, latitude];
this.currentCenter = ol.proj.fromLonLat(center);
console.log('update center of the map with latitude = '+latitude+' and longitude = '+longitude);
this.currentView.centerOn(this.currentCenter,[400,400], [0,0]);
},
});
})();
</script>
And the call in Polymer :
<openlayer-map latitude="48.853" longitude="2.35" geotracking></openlayer-map>
Any clue ?
Found it ! Needed to do the map initialization in an asynchronous call
attached: function()
{
this.async(function()
{
this.initialConfig(); // Create your ol.Map here
});
},