It's been few days i'm trying to make Openlayers work with my Django web site.
I'm totally a noob in Web, so I might miss straightforward stuff that I'm not able to understand, yet.
From what I understand, I need to load Openlayers, so for this in my index.html, I've added in the <head> this :
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.3.1/build/ol.js"></script>
Then in the <body> I've added the index.js where I would like to work with openlayers:
<script src="{% static 'index.js'%}"></script>
I've copy paste a simple example in the index.js and it's been working correctly.
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([2.333333, 48.866667]),
zoom: 10
})
});
So I have a map centered on Paris. Now I would like to load a GeoJson file, thus I need to add a Layer containing the GeoJon. For this I've followed an example here.
Here is my first problem I tried to import like this : import GeoJSON from 'ol/format/GeoJSON';
or like this import Style from ol.style.Style bit I got this error : Uncaught SyntaxError: Cannot use import statement outside a module
The only solution I found was to new ol.style.Style(...) when I needed to use it. Ugly, but working.
So I've delete all the import and used the full path of each class to call the constructors. Until one of them would not work.
var vectorLayer = new ol.layer.Vector.VectorLayer({
source: new ol.source.Vector.VectorSource({
url: 'data/geojson/countries.geojson',
format: new ol.format.GeoJSON()
}),
style: function(feature) {
style.getText().setText(feature.get('name'));
return style;
}
});
Uncaught TypeError: ol.source.Vector.VectorSource is not a constructor
https://openlayers.org/en/latest/apidoc/module-ol_source_Vector-VectorSource.html
So I'm asking my self why it is not working, and how is it possible to make it less ugly (to use the Imports)
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
You can check the OpenLayers 4 examples https://openlayers.org/en/v4.6.5/examples/ for full build syntax
Related
I a trying to render a basic map with mapbox and svelte kit. The mapbox-code comes directly from this example here: https://docs.mapbox.com/help/tutorials/choropleth-studio-gl-pt-2/
I want to simply create this map in the src/lib/mapboxmap.svelte-compontent, import it into the +page-route and render it. Yet I am always getting a 500 internal error.
I think I'm simply misunderstanding something. Probably of how svelte kit works. This is the minimal mapboxmap.sveltecomponent:
<script>
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// define access token
mapboxgl.accessToken =
'pk.eyJ1Ijoicm9iaW5rb2hycyIsImEiOiJjanU5am95bm4xZnZ6NDNrOTRyYTYwdzJzIn0.iMFQgQIlhz36wB3819Xftw';
// create map
const map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim' // map style URL from Mapbox Studio
});
console.log('map: ', map);
</script>
I am then importing it into he src/routes/+page.svelte route like this:
<script>
import Mapboxmap from '../lib/mapboxmap.svelte';
</script>
<Mapboxmap />
And this is the result:
I think it might be a silly question, but I can't find the solution right now
You need to move the mapbox initialization part within an onMount block.
Otherwise, this code is run server-side and mapbox server won't like it, plus DOM being not initialized, the container 'map' does not exist yet (not to mention you actually have to insert it in your HTML block).
Something of the like will work :
<script>
import {onMount} from 'svelte'
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
let map;
onMount(async()=>{
mapboxgl.accessToken =
'pk.eyJ1Ijoicm9iaW5rb2hycyIsImEiOiJjanU5am95bm4xZnZ6NDNrOTRyYTYwdzJzIn0.iMFQgQIlhz36wB3819Xftw';
// create map
map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim' // map style URL from Mapbox Studio
});
})
</script>
<div id="map">
When I'm trying to call a js function named initMap via interop in a hybrid blazor app, I keep getting the following error:
Could not find 'initMap' in 'window'
I have the following code:
TestApp.Windows\wwwroot\index.html
...
<head>
<script src="../js/initGoogleMap.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=&callback=initMap"></script>
</head>
...
TestApp.Windows\wwwroot\js\initGoogleMap.js
window.initGoogleMap = {
initMap: function () {
const latLng = new google.maps.LatLng(40.716948, -74.003563);
const options = {
zoom: 14,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
const map = new google.maps.Map(document.getElementById("map"), options)
}
};
TestApp\WebUI\Pages\Index.razor
#page "/"
#inject IJSRuntime JSRuntime
<h1>Hello, world!</h1>
Welcome to your new app.
<div id="map" style="height:500px; width:100%;"></div>
#code{
protected override async Task OnAfterRenderAsync(bool firstRender) {
if (firstRender)
{
Console.WriteLine("first render");
await JSRuntime.InvokeVoidAsync("initMap");
}
}
}
Any ideas why this error occurs? I tried several small tweaks but to no avail. Any help would be greatly appreciated!
Try await JSRuntime.InvokeVoidAsync("initGoogleMap.initMap");
https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-javascript-from-dotnet?view=aspnetcore-5.0#capture-references-to-elements
Most likely the static files are not copied in the working directory. Here are some steps to deal with the issue:
In the common project make sure all static resources are set to
"copy if newer" (in the file's properties)
In index.html file, please set the file path to match the following pattern:
"_content/<PROJECT_NAME>/path/to/the/file.js"
In your case that would be:
"_content/TestApp/js/initGoogleMap.js"
Delete all bin and obj folders in every project and rebuild whole solution.
If issue persists for Android, please Uninstall the app from the android emulator and repeat step 3.
P.S. Here's a link to the issue in Blazor Binding's repo: https://github.com/dotnet/MobileBlazorBindings/issues/211
Complete error:
layerSwitcherDemo.js:52 Uncaught ReferenceError: ol is not defined
at Module../app/javascript/packs/layerSwitcherDemo.js (layerSwitcherDemo.js:52)
at __webpack_require__ (bootstrap:19)
at bootstrap:83
at bootstrap:83
./app/javascript/packs/layerSwitcherDemo.js # layerSwitcherDemo.js:52
__webpack_require__ # bootstrap:19
(anonymous) # bootstrap:83
(anonymous)
This is called from people/show.html.erb via <%= javascript_pack_tag 'layerSwitcherDemo' %>.
If I use the same <%= javascript_pack_tag 'layerSwitcherDemo' %> from map/ol_layer_switcher.html.erb the script works fine.
// javascript/packs/layerSwitcherDemo.js
import Map from 'ol/Map';
import View from 'ol/View';
import { transform } from 'ol/proj';
import LayerGroup from 'ol/layer/Group';
import LayerImage from 'ol/layer/Image';
import LayerTile from 'ol/layer/Tile';
import SourceOSM from 'ol/source/OSM';
import XYZ from 'ol/source/XYZ';
import LayerSwitcher from 'ol-layerswitcher';
import {transformExtent, fromLonLat} from 'ol/proj';
var <a long list>
// the next line is line 52 in the error
var map = new ol.Map({
target: 'map',
layers: [
// rest of the code
I'm trying to build up slowly to make an OpenLayers map. I'll use something different than LayerSwitcherDemo which I made just to make sure it would load in Rails. Layer Switcher is a demo that I modified.
Just thought to compare the compiled layerSwitcherDemo-xx.js script and all 55k lines are identical. application-xx.js are identical.
Fixed now but not solved. The page that was working loaded the CDN version of OpenLayers. Being new to Webpack I'm not sure which is best. I guess it's less code I'm carrying along. Let the CDN do it. This will be a very lightly used app. I'm guessing I need some kind of definition equivalent to import $ from 'jquery'
In your example, you're calling ol.Map, but you've imported Map. Edit your Webpack JS as follows:
import Map from 'ol/Map'
// ... other imports
const map = new Map({ // replaces ol.Map
target: 'map',
layers: [
// ...
OR, the following will work for some imports according to the main entry point in the the openlayer module.
import * as ol from 'ol';
new ol.Map() // but not ol.LayerGroup, for example ...
Included in posting. I fixed by using the OpenLayers CDN and not relying on webpack to load ol. The following is the Resources for the page that does NOT work. ol (openlayers) is there.
I see that OpenLayers 5.3.0 is making use of observables. The docs also cover events.
How would I alter this starting example to .subscribe() to events in general? I'm struggling bridging the gap between docs and use.
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
new Map({
target: 'map',
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
})
});
I've seen examples with older versions of OpenLayers that may not apply here. At least in the linked example above, "eventListeners" is not listed as a property on 5.3.0 and seems old and callback-related (not observable).
I did see a more recent, similar question here with helpful resources listed. I could use a script example to help get started.
You can register events, for example on the map. In the latest examples there is an example for the moveend event.
var map = new Map({
layers: [
new TileLayer({
source: new OSM()
})
],
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
})
});
map.on('moveend', function(evt){console.log(evt);});
I'm developing a library that uses ArcGIS which based on dojo framework.
ArcGIS has main file that we include in the <script> Tag. And then we simple require their modules using require('esri/map'....
My es6 library has allot of modules and part of them need to use ArcGIS modules.
I'm using webpack and babel to bundle and transform the code. I'm not bundling ArcGIS in my library single file. I'm expecting my clients to include esri adding <script> and then include my bundle using <script>.
There I've already met an obstacle - dojo multiple define... So I've made another js excluded from the bundle that loads my bundle file using dojo require that already exist (Cause arcgis is up already and loaded dojo).
Now, the second problem I don't manage to solve is to load other ArcGIS AMD modules..
I have my class MyMap.js
export default MyMap {
constructor() {
// Adding here code to create ArcGIS Map
// this.map = new esriMap....
}
}
esriMap does not exist and must be loaded. In a simple application we would do this to make it happen
require([
"esri/Map",
"esri/views/MapView"
], function(Map, MapView) {
var map = new Map({
basemap: "streets"
});
var view = new MapView({
container: "viewDiv",
map: map,
zoom: 4,
center: [15, 65]
});
});
but this does not work.
someone ?
for using dojo's require we need simply to write window.require and it will work.
without writing window. it is failing in the build process Can't resolve 'esri/Map'
For esri users who wants to use some nice loader - check out this one
code example:
export default class myMap {
constructor(div) {
window.require(['esri/Map', 'esri/views/MapView'], (esriMap, esriMapView) => {
const map = new esriMap({
basemap: "streets"
});
const view = new esriMapView({
container: div,
map: map,
zoom: 4,
center: [15, 65]
});
});
}
}