why openlayers map not working in vue-cli 3 - javascript

I have added ol package to my vue-cli project through
npm install ol
but the map doesn't load. there is no error and I just find an empty div in the result source.
here is my code =>
the html part :
<div id="map-container"></div>
the js part :
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZSource from 'ol/source/XYZ';
export default {
name: "page",
data() {
return {
...
}
},
methods: {
initMap: function () {
new Map({
target: 'map-container',
view: new View({
center: [0, 0],
zoom: 2
})
});
},
mounted: function () {
this.initMap();
},
}
NOTE => some where I found that I have to call init function as :
this.$nextTick(function () {
initMap();
})
but it made no difference.
guys, I'm running out of time so pls help me.
thanks everybody who wanna help

It looks like you are missing a TileLayer. Something like this:
new Map({
target: "map-container",
layers: [
new TileLayer({
source: new XYZ({
url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
})
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});

Related

Openlayers WMTS custom configuration problem

I am trying to use WMTS layers in opnelayers project. This is my firt time when I try to use WMTS instead of WMS. Unfortunatelly I am stuck. I have no idea how to set up.
PLease help me to set up correct settings:
WMTS url GetCapabilities
my code (I used template from example on opnelayers.org):
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import WMTS from 'ol/source/WMTS.js';
import WMTSTileGrid from 'ol/tilegrid/WMTS.js';
import {get as getProjection} from 'ol/proj.js';
import {getTopLeft, getWidth} from 'ol/extent.js';
const projection = getProjection('EPSG:4326');
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = new Array(19);
const matrixIds = new Array(19);
for (let z = 0; z < 19; ++z) {
// generate resolutions and matrixIds arrays for this WMTS
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
const map = new Map({
layers: [
new TileLayer({
source: new OSM(),
}),
new TileLayer({
opacity: 0.7,
source: new WMTS({
url: 'https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution?SERVICE=WMTS&REQUEST=GetCapabilities',
layer: 'ORTOFOTOMAPA',
matrixSet: 'EPSG:2180',
format: 'image/png',
projection: projection,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds,
}),
// style: 'default',
wrapX: true,
}),
}),
],
target: 'map',
view: new View({
center: [2008582, 6753697],
zoom: 7,
}),
});
Thanks!
If you have a custom projection there will also be a custom tile grid, so it is easier to parse the capabilities and let OpenLayers obtain the options. You will also need to define and register the EPSG:2180 projection (including the N-E axis order) using proj4.
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/Tile.js';
import View, {createRotationConstraint} from 'ol/View.js';
import WMTS, {optionsFromCapabilities} from 'ol/source/WMTS.js';
import WMTSCapabilities from 'ol/format/WMTSCapabilities.js';
import proj4 from 'proj4';
import {register} from 'ol/proj/proj4';
proj4.defs(
'EPSG:2180',
'+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs +axis=neu'
);
register(proj4);
const wmtsLayer = new TileLayer({
opacity: 0.7,
});
const map = new Map({
layers: [
new TileLayer({
source: new OSM(),
}),
wmtsLayer,
],
target: 'map',
view: new View({
center: [2008582, 6753697],
zoom: 7,
}),
});
const parser = new WMTSCapabilities();
fetch(
'https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMTS/HighResolution?SERVICE=WMTS&REQUEST=GetCapabilities'
)
.then(function (response) {
return response.text();
})
.then(function (text) {
const result = parser.read(text);
const options = optionsFromCapabilities(result, {
layer: 'ORTOFOTOMAPA',
matrixSet: 'EPSG:2180',
});
wmtsLayer.setSource(new WMTS(options));
});
https://codesandbox.io/s/wmts-layer-from-capabilities-forked-6gu26y?file=/main.js

Openlayer WMS GetFeatureInfo response null

I'm facing a problem with GetFeatureInfo from WMS layer (published by my own via geoserver). After singleClick I have response no value. The WMS layers is EPSG 3857 like map view as well.
I have been trying with example from openlayer and everything works fine.
I do not have any idea what is wrong. Please find below my main.js file
import './style.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import TileWMS from 'ol/source/TileWMS';
const wmsSource1 = new TileWMS({
url: 'https://portal.solarmap.pl/geoserver/ows?service=wms',
params: {'LAYERS': 'solarmap-swidnica:VEG_IRR_FIELD_4'},
serverType: 'geoserver',
// projection: 'EPSG:3857',
crossOrigin: 'anonymous',
});
const basemap = new TileLayer({
source: new OSM(),
});
const wmsLayer1 = new TileLayer({
source: wmsSource1,
});
const view = new View({
center: [0, 0],
zoom: 1,
});
const map = new Map({
layers: [basemap, wmsLayer1],
target: 'map',
view: new View({
projection: 'EPSG:3857',
center: [1833048, 6593400],
zoom: 18,
}),
})
map.on('singleclick', function (evt) {
// document.getElementById('info').innerHTML = '';
const viewResolution = /** #type {number} */ (view.getResolution());
const url = wmsSource1.getFeatureInfoUrl(
evt.coordinate,
viewResolution,
'EPSG:3857',
{'INFO_FORMAT': 'text/html'}
);
console.log(url);
if (url) {
fetch(url)
.then((response) => response.text())
.then((html) => {
document.getElementById('info').innerHTML = html;
});
}
});
I have chekced the WMS layer by goeserver - preview. There is a possibility to view feature value, so the problem is not in WMS I hope.
Link to the WMS preview:
preview WMS

Using local GEOJson with OpenLayers

I am a relative beginner to using OpenLayers so I was playing around with some of the examples given on the OpenLayers website. When trying the image-vector-layer example, I had a problem where it would work fine with a json online, but when using a local geojson file the response under the networks section for the geojson file would be an html instead, giving the error "Unexpected token < in JSON at position 0". Attached is my javascript below, the error is occurring at the "url: data/countries.geojson". Is there any way I can use a local file instead of an online link? Thank you!
import 'ol/ol.css';
import GeoJSON from 'ol/format/GeoJSON';
import Map from 'ol/Map';
import VectorImageLayer from 'ol/layer/VectorImage';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import {Fill, Stroke, Style} from 'ol/style';
const style = new Style({
fill: new Fill({
color: '#eeeeee',
}),
});
const vectorLayer = new VectorImageLayer({
background: 'lightblue',
imageRatio: 2,
source: new VectorSource({
url: 'data/countries.geojson',
format: new GeoJSON(),
}),
style: function (feature) {
const color = feature.get('COLOR') || '#eeeeee';
style.getFill().setColor(color);
return style;
},
});
const map = new Map({
layers: [vectorLayer],
target: 'map',
view: new View({
center: [0, 0],
zoom: 1,
}),
});
const featureOverlay = new VectorLayer({
source: new VectorSource(),
map: map,
style: new Style({
stroke: new Stroke({
color: 'rgba(255, 255, 255, 0.7)',
width: 2,
}),
}),
});
let highlight;
const displayFeatureInfo = function (pixel) {
const feature = map.forEachFeatureAtPixel(pixel, function (feature) {
return feature;
});
const info = document.getElementById('info');
if (feature) {
info.innerHTML = feature.get('ECO_NAME') || ' ';
} else {
info.innerHTML = ' ';
}
if (feature !== highlight) {
if (highlight) {
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}
};
map.on('pointermove', function (evt) {
if (evt.dragging) {
return;
}
const pixel = map.getEventPixel(evt.originalEvent);
displayFeatureInfo(pixel);
});
map.on('click', function (evt) {
displayFeatureInfo(evt.pixel);
});

Make Icon change position to mouse click spot in Open Layers 6

How do you make it so wherever you click on the map, the Icon added on the map just instantly teleports to those coordinates? Currently in the official Open Layers 6 'Examples' page, it shows the drag and drop example with the following example:
import 'ol/ol.css';
import Feature from 'ol/Feature';
import Map from 'ol/Map';
import Point from 'ol/geom/Point';
import TileJSON from 'ol/source/TileJSON';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View';
import {Icon, Style} from 'ol/style';
import {Modify} from 'ol/interaction';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
const iconFeature = new Feature({
geometry: new Point([0, 0]),
name: 'Null Island',
population: 4000,
rainfall: 500,
});
const iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'data/icon.png',
}),
});
iconFeature.setStyle(iconStyle);
const vectorSource = new VectorSource({
features: [iconFeature],
});
const vectorLayer = new VectorLayer({
source: vectorSource,
});
const rasterLayer = new TileLayer({
source: new TileJSON({
url: 'https://a.tiles.mapbox.com/v3/aj.1x1-degrees.json?secure=1',
crossOrigin: '',
}),
});
const target = document.getElementById('map');
const map = new Map({
layers: [rasterLayer, vectorLayer],
target: target,
view: new View({
center: [0, 0],
zoom: 3,
}),
});
const modify = new Modify({
hitDetection: vectorLayer,
source: vectorSource,
});
modify.on(['modifystart', 'modifyend'], function (evt) {
target.style.cursor = evt.type === 'modifystart' ? 'grabbing' : 'pointer';
});
const overlaySource = modify.getOverlay().getSource();
overlaySource.on(['addfeature', 'removefeature'], function (evt) {
target.style.cursor = evt.type === 'addfeature' ? 'pointer' : '';
});
map.addInteraction(modify);
Their wiki does not mention about any convenient property like Icon.setPosition. Thank you.
You add a click listener to the map and change the geometry of the feature:
map.on('click', function (event) {
iconFeature.getGeometry().setCoordinates(event.coordinate);
});

Error when trying to set zoom using SceneView

Using esri-loader, when trying to create a SceneView using the following the view is not calculating the zoom correctly and I'm getting the following errors in the console:
[esri.views.3d.support.cameraUtils] #zoomToScale() Cannot compute scale from zoom without a tiling scheme
client-hook-3.js:1 [esri.views.3d.state.ViewStateManager] #zoom= Invalid zoom 3
let map = new WebMap({
portalItem: {
id: MAP_ID_HERE
}
});
let view = new SceneView({
container: "map",
viewingMode: "local",
map: map,
zoom: 3
});
Does anyone happen to know what is causing this? Looking through the documentation for SceneView it seems this should be valid in the constructor.
I think in this particular case, using a web map as the map, you have to wait for the view to load in order to set the zoom level. If not it will not be able to calculate the scale, that is the cause of the error.
This should work,
let view = new SceneView({
container: "map",
map: map,
viewingMode: "local"
});
view.when(function() {
view.zoom = 3;
});
UPDATE: (leave the other code because I think it clarify the problem and the final answer)
Well it seems that is not enough to wait for the view, because the basemap could not load everything. So here you have an alternative that works,
const basemap = Basemap.fromId("dark-gray-vector");
const sceneView = new SceneView({
container: this.$el,
map: new WebMap({
basemap,
}),
center: [US_CENTER.longtitude, US_CENTER.latitude],
viewingMode: "local"
});
basemap.loadAll().then(
() => {
sceneView.goTo({ zoom: 3 });
}
);
In this new solution we actually wait till the basemap loads everything (using loadAll method) an then we set the zoom of the view.
This is the full code in your Map.vue,
<template>
<div />
</template>
<script>
import { loadArcGISModules } from "#deck.gl/arcgis";
const US_CENTER = { longtitude: -98.5795, latitude: 39.8283 };
export default {
name: "Map",
props: {},
mounted() {
loadArcGISModules(
[
"esri/WebMap",
"esri/views/SceneView",
"esri/Basemap",
],
{ css: true }
).then(({ DeckRenderer, modules }) => {
const [WebMap, SceneView, Basemap] = modules;
const basemap = Basemap.fromId("dark-gray-vector");
const sceneView = new SceneView({
container: this.$el,
map: new WebMap({
basemap,
}),
center: [US_CENTER.longtitude, US_CENTER.latitude],
viewingMode: "local"
});
basemap.loadAll().then(
() => {
sceneView.goTo({ zoom: 3 });
}
);
});
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
div {
width: 100%;
height: 100%;
}
</style>

Categories

Resources