I am working for the first time on open layers (angular 4).
after installing and importing files in ts.
these are the imported files
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
import TileWMS from 'ol/source/TileWMS.js';
new ol.Map({
I am getting this error
Cannot find name 'ol'.
new ol.Map({ should be new Map({, see the simple map example in the documentation
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
var map = new Map({
layers: [
new TileLayer({
source: new OSM()
})
],
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
})
});
Related
I'm trying to learn Svelte / SvelteKit by porting over an existing Angular application. The app should show a Leaflet map with a heatmap layer as overlay. The map part works and is robust, even when I navigate or refresh Svelte handles it fine. The heatmap on the other hand only loads when the app initializes for the first time as you can see here:
However When I refresh I get this error and the whole Map.svelte component doesn't load at all anymore with the following error message in the console:
Uncaught (in promise) TypeError: Leaflet.heatLayer is not a function
I suspect it has to do with the way the lifecycle handles imports, because in my Angular app the imports don't have to be done in a life cycle method in order for them to work, whereas the only way to get Leaflet to even render in SvelteKit I have to do an async import.
Can anyone clarify what's going on with the Leaflet.heatlayer error and how I can fix it?
Map.svelte
<script lang="ts">
import type { HeatLayer, Map } from 'leaflet';
import { onMount } from 'svelte';
let Leaflet;
let map: Map;
let heatLayer: HeatLayer;
onMount(async () => {
Leaflet = await import('leaflet');
import('leaflet.heat');
const heatLatLngTuple = await fetchData(); // fetchData returns data from JSON file
const mapTiles = Leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
});
heatLayer = Leaflet.heatLayer(heatLatLngTuple, {. // THIS LINE IS CAUSING THE ERROR
radius: 20,
blur: 25,
minOpacity: 0,
maxZoom: 6,
max: 12
});
map = Leaflet.map('map', {
center: [51.505, -0.09],
zoom: 6,
layers: [mapTiles, heatLayer]
});
});
</script>
<div id="map" />
Things I've tried:
including 'leaflet-heat.js' from node_modules in a <script> tag in app.html
including 'leaflet-heat.js' from node_modules in a <script> tag in __layout.svelte
including 'leaflet-heat.js' from node_modules in a <script> tag in index.svelte
importing leaflet.heat at the top of Map.svelte with "import 'leaflet.heat'" <- THIS WORKED IN ANGULAR! but here it just results in this error
ReferenceError: window is not defined
putting a tick() before assigning heatLayer in Map.svelte
Resources:
My GitHub repo
Leaflet.heat
As this answer points out there is an additional way of importing that I didn't know about using
vite-plugin-iso-import
After getting that set up my component now works and after importing "leaflet.heat" with ?client added and moved to the top level of my imports. Here is the link to the FAQ with a detailed explanation.
After the changes my component now looks like this:
Map.svelte
<script lang="ts">
import type { HeatLayer, Map } from 'leaflet';
import { onMount } from 'svelte';
import Leaflet from 'leaflet?client'; // provides definition of 'L' needed by Leaflet
import 'leaflet.heat?client'; // Note the '?client' after the module name which makes sure 'leaflet.heat' always has access to the 'window' object
let map: Map;
let heatLayer: HeatLayer;
onMount(async () => {
const heatLatLngTuple = await fetchData();
const mapTiles = Leaflet.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
});
heatLayer = Leaflet.heatLayer(heatLatLngTuple, {. // THIS LINE IS CAUSING THE ERROR
radius: 20,
blur: 25,
minOpacity: 0,
maxZoom: 6,
max: 12
});
map = Leaflet.map('map', {
center: [51.505, -0.09],
zoom: 6,
layers: [mapTiles, heatLayer]
});
});
</script>
<div id="map" />
I had this same issue on refresh, you need import the module inside the on mount. It's not the same as your code. But you get that point.
onMount(async () => {
const leafletModule = await import('leaflet');
L = leafletModule.default;
I loaded .shp file inside QGIS, and exported it from there using Export to PostgreSQL command in Processing Toolbox pane.
Then I started pg_tileserv.exe to serve vector tiles, and as you can see in this screenshot - it is visible in the browser (blue contour lines).
The problem I'm having is to display these vector tiles inside QGIS if added as XYZ Tiles (or if I try to display in browser with my code and OpenLayers js lib.). As you can see in this screenshot, I added XYZ Tiles, but it just stays blank - I cannot see the map in the right pane (in screenshot, checkbox is not checked, but nothing happens even if checked. I also tried changing styles etc...):
And if I load data directly from PostgreSQL, it loads and shows OK:
Anybody knows what could be a problem here?
UPDATE
As #JGH said, I should use Vector Tiles from list. Now just to see why OpenLayers config is not rendering it:
import 'ol/ol.css';
import MVT from 'ol/format/MVT';
import Map from 'ol/Map';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import View from 'ol/View';
import {Fill, Icon, Stroke, Style, Text} from 'ol/style';
const key =
'';
const map = new Map({
layers: [
new VectorTileLayer({
declutter: true,
source: new VectorTileSource({
attributions:
'© Mapbox ' +
'© <a href="https://www.openstreetmap.org/copyright">' +
'OpenStreetMap contributors</a>',
format: new MVT(),
url:
'http://localhost:7800/public.simplified_land_polygons/' +
'{z}/{x}/{y}.pbf' +
key,
}),
style: createMapboxStreetsV6Style(Style, Fill, Stroke, Icon, Text),
}),
],
target: 'map',
view: new View({
center: [0, 0],
zoom: 1,
}),
});
UPDATE 2
Yes, it was due to styles. After changing, it is visible now!
style: new Style({
fill: new Fill({
color: 'red'
}),
stroke: new Stroke({
color: 'white',
width: 1.25
}),
image: new Circle({
radius: 5,
fill: new Fill({
color: 'red'
}),
stroke: new Stroke({
color: 'white',
width: 1.25
})
})
I am trying to include a map in my application. I load data from a postgis database, where it is stored as wgs84. The data is loaded as geojson and displayed by open layers.
The problem is that the data is currently being projected somewhere in the ocean, I therefore suspect the data needs to be translated into a different coordinate system.
This is the code to create the map object:
var map = new ol.Map({
projection: 'EPSG:4326',
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
})
],
view: new ol.View({
center: ol.proj.fromLonLat([5, 52]),
zoom: 4
})
});
And this is the code I use to load the data:
function addObjectsToMap()
{
var vectorSource = new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures( <?php print_r($object->getLocationsAsGeoJson()); ?> )
});
var vectorLayer = new ol.layer.Vector(
{
source: vectorSource
});
map.addLayer(vectorLayer);
}
I have already tried setting the coordinate system of the map to epsg:900913,
I tried adding this in the vectorLayer:
preFeatureInsert: function(feature)
{
feature.geometry.transform(new ol.proj.Projection("EPSG:4326"),new ol.proj.Projection("EPSG:900913"));
},
I tried adding: .transform('EPSG:4326','EPSG:900913') to the dataimport (where the vector source is created)
And I tried looping over the the data in my vectorsource like this:
vectorSource.getFeatures()[i].setGeometry(vectorSource.getFeatures()[i].getGeometry().transform(new ol.proj.Projection("EPSG:4326"),new ol.proj.Projection("EPSG:900913")));
I would really appreciate it if someone could point me in the right direction. Surely this is something common and should be very easy to deal with. But I cannot find anything about it in the documentation or examples of open layers.
The features can be transformed to the view projection using dataProjection and featureProjectiion options when reading the features
features: new ol.format.GeoJSON().readFeatures( <?php print_r($object->getLocationsAsGeoJson()); ?> , {
dataProjection: 'EPSG:4326',
featureProjection: map.getView().getProjection()
})
I use vector tiles in crs ETRS89/UTM zone 32N (EPSG:25832) in OpenLayers and it works properly with default style.
But my problem is that if I apply a style.json from Maputnik in form of Mapbox Style by using th library olm-mapbox-style, it will be ignored. The same style.json works fine with "EPSG:3857".
I guess it is related to view because the olms uses map.getView().getZoom() function by updating the style.
How can I resolve this problem? Any idea?
Many thanks.
...
import {apply, applyStyle} from 'ol-mapbox-style';
...
proj4.defs("EPSG:25832","+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
register(proj4);
var projection = getProjection("EPSG:25832");
const map = new Map({
target: 'map',
layers:[
new TileLayer({
source: new OSM()
}),
vectorTile
],
view: new View({
center: transform([7.012, 51.4], "EPSG:4326", projection),
projection:projection,
zoom: 6
})
});
const jsonPath = require('./data/style.json');
apply(map, jsonPath);
The OSM map won't show anymore with Openlayers 5
I tried to added from ol.source.OSM() but a grey map shown.
var map3 = new ol.Map({
layers: new ol.layer.Tile({
source: new ol.source.OSM()
}) ,
target: 'map-id3',
view: new ol.View({
center:ol.proj.fromLonLat([10.74,34.77]),
zoom:12
})
});
layers must be an array
layers: [ new ol.layer.Tile({
source: new ol.source.OSM()
}) ],