How to user openlayers js in alpinejs - javascript

I am trying to get openlayer working in alpine
but i have this error which i can't solve
Uncaught SyntaxError: ambiguous indirect export: default
(import olJf from "./dist/js/oljf.js";)
My source file
//oljf.js
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';
export default function olJf () {
new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: [0, 0],
zoom: 2,
}),
})
};
I compile it with vitejs and I import it in my alpine component
//compiled file
import olJf from "./dist/js/oljf.js";
document.addEventListener('alpine:init', () => {
Alpine.data('map', () => ({
latitude: false,
longitude: false,
isLoading: false,
init() {
console.log(`map for ${this.latitude}`);
console.log(window.oljf)
const mapdiv = document.getElementById('openmap_offre')
olJf()
}
})
)
})
And I call alpine
<head>
<script type="module" src="https://xxx.be/wp-content/themes/visittail/assets/js/map.js" defer></script>
</head>
<body>
<div id="openmap_offre" class="mt-3" style="width: 100%; height: 400px;" x-data="map" x-init="initMap">
</div>
</body>

Related

FlyTo on existing Mapbox Object in Svelte

I have a Svelte application with a Map component as below. I'd like to pass in props for centreCoords and Zoom and then fly to them when they change outside the component.
However, I can't work out how to get the map object outside the onMount function.
<script>
import { onMount, onDestroy } from 'svelte';
import mapboxgl from 'mapbox-gl';
const token = 'xxx';
let mapElement;
let map;
export let zoom;
export let centreCoords = [];
// This but doesn't work
map.flyTo({
center: centreCoords,
zoom: zoom,
essential: true // this animation is considered essential with respect to prefers-reduced-motion
});
onMount(() => {
mapboxgl.accessToken = token;
map = new mapboxgl.Map({
container: mapElement,
zoom: zoom,
center: centreCoords,
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/light-v10',
antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});
});
onDestroy(async () => {
if (map) {
map.remove();
}
});
</script>
<main>
<div bind:this={mapElement} />
</main>
<style>
#import 'mapbox-gl/dist/mapbox-gl.css';
main div {
height: 800px;
}
</style>
Should be possible to just use a reactive statement with an if:
$: if (map) map.flyTo(...)

Vuelayers "projection.getCode is not a function" when using ol/proj module

I'm trying to use the vuelayers API in a vue application. I've imported ol itself too, as I couldn't get the ol-ext module to work. When trying to use the proj functions (specifically addProjection()) I get the following error:
Uncaught TypeError: projection.getCode is not a function
main.js
import { createApp } from 'vue'
import App from './App.vue'
import VueLayers from 'vuelayers'
import 'vuelayers/dist/vuelayers.css'
import 'ol'
createApp(App).mount('#app')
ExampleComp.vue
<template>
<vl-map :load-tiles-while-animating="true" :load-tiles-while-interacting="true" style="height: 400px">
<vl-view :projection="projection" :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation"></vl-view>
<vl-layer-image id="xkcd">
<vl-source-image-static :url="imgUrl" :size="imgSize" :extent="imgExtent" :projection="projection"
:attributions="imgCopyright"></vl-source-image-static>
</vl-layer-image>
</vl-map>
</template>
<script>
import { addProjection, createProjection } from 'ol/proj'
let size = [1024, 968]
let extent = [0, 0, ...size]
let customProj = createProjection({
code: 'xkcd-image',
units: 'pixels',
extent,
})
addProjection(customProj)
export default {
data () {
return {
zoom: 2,
maxZoom: 8,
center: [size[0] / 2, size[1] / 2],
rotation: 0,
projection: customProj.getCode(),
imgUrl: 'https://imgs.xkcd.com/comics/online_communities.png',
imgCopyright: '© xkcd',
imgSize: size,
imgExtent: extent,
}
},
}
</script>
I don't have enough experience with this to know if the absence of a getCode() function is an issue with the module of my code.

Click on zoom button trigger go thought all div and trigger my map function Anuglar10 / OpenLayer6

I have an issue using event with OpenLayers and Angular, I have an function on click on my map which catch me the lonlat from where I have clicked on the map but, when I click on the zoom in and out control the function is also triggered same thing when I drag my view which I don't what to happen. It's the first time i'm using this API, can someone help me ?
my TS file
import { Component, OnInit } from '#angular/core';
import Map from 'ol/Map';
import Tile from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import View from 'ol/View';
import { fromLonLat, transform } from 'ol/proj';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import { Feature } from 'ol';
import Point from 'ol/geom/Point';
import Style from 'ol/style/Style';
import Icon from 'ol/style/Icon'
#Component({
selector: 'app-indicator-acceuil',
templateUrl: './indicator-acceuil.component.html',
styleUrls: ['./indicator-acceuil.component.scss']
})
export class IndicatorAcceuilComponent implements OnInit {
map: any;
markerSource: VectorSource = new VectorSource({});
constructor() { }
ngOnInit(): void {
this.initilizeMap();
}
initilizeMap() {
this.map = new Map({
target: 'map',
layers: [
new Tile({
source: new OSM()
}),
new VectorLayer({
source: this.markerSource,
style: new Style({
image: new Icon({
anchor : [0.5,1],
src: 'assets/pin24x24.png',
scale : 1.5,
imgSize: [24,24],
})
})
})
],
view: new View({
center: fromLonLat([2.213749,46.227638]),
zoom: 6
}),
});
}
getCoord(event: any) {
const coordinate = this.map.getEventCoordinate(event);
let lonlat = transform(coordinate, 'EPSG:3857', 'EPSG:4326');
const lon = lonlat[0];
const lat = lonlat[1];
console.log(lonlat)
this.addMarker(lon, lat);
}
addMarker(lon: number, lat: number) {
this.markerSource.clear();
let marker = new Feature({
geometry: new Point(fromLonLat([lon,lat])) // dont worry about coordinate type 0,0 will be in west coast of africa
});
this.markerSource.addFeature(marker)
}
}
My html file
<div id="map" (click)="getCoord($event)"></div>

How to use Javascript Files instead of NPM as a Library (Specifically for Open Layers)

I have been trying to get open layers to work in my Eclipse web development environment for a while now. All of the setup instructions on the Open Layers site deal with using npm. However, they also have a link to a distro that has ol.js, ol.js.map, ol.css, and ol.css.map in it. In their workshop, they have a javascript file that looks like this:
import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZSource from 'ol/source/XYZ';
import {fromLonLat} from 'ol/proj';
new Map({
target: 'map-container',
layers: [
new TileLayer({
source: new XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
})
})
],
view: new View({
center: fromLonLat([0, 0]),
zoom: 2
})
});
What I am struggling with is how to modify it to use the java script files instead of the npm libraries. I imagine this part would be the only thing that would change.
import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZSource from 'ol/source/XYZ';
import {fromLonLat} from 'ol/proj';
I tried to put the files in a folder and change the import code to:
import './lib/ol.css'
import {Map, View} './lib/ol.js'
import TileLayer from './lib/ol.js';
import XYZSource from './lib/ol.js';
import {fromLonLat} from './lib/ol.js';
That didn't work. Probably because I don't totally understand what's happening. I read that a js file can be used as a library, so I thought I could just reference the file.
They also have an html file as part of tutorial, since I am not using npm, do I have to change that as well? I assume since they are instructing to put both the js file and the html file at the root of the project they can just reference the other (as the js file would import the css and html file would use that), but I'm not totally sure. This is the html for reference:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenLayers</title>
<style>
html, body, #map-container {
margin: 0;
height: 100%;
width: 100%;
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="map-container"></div>
</body>
</html>
Can anyone help me out? Thank you for your time.
If you want to use ol.js, ol.css; you need to use the namespace ol. in the code.
An example of how to do this is shown in the quickstart guide
Modifying your posted code:
new ol.Map({
target: 'map-container',
layers: [
new ol.layer.Tile({ // TileLayer({
source: new ol.source.XYZ({ // XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([0, 0]),
zoom: 2
})
});
working code snippet:
new ol.Map({
target: 'map-container',
layers: [
new ol.layer.Tile({ // TileLayer({
source: new ol.source.XYZ({ // XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([0, 0]),
zoom: 2
})
});
html, body, #map-container {
margin: 0;
height: 100%;
width: 100%;
font-family: sans-serif;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.3.1/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.3.1/build/ol.js"></script>
<div id="map-container"></div>
Remove all the import lines from the JavaScript. Include the ol.js script directly with
<script src="path_to_your_copy/ol.js"></script>
then preface everything in the OpenLayers javascript namespace with ol as mentioned by #geocodzip e.g.
new ol.Map(...);

VUE + google map how include api google

I started using vue. How can I include Google API to my page? This is my code:
<template>
<div id="map"></div>
</template>
<script>
export default {
methods: {
init () {
var map
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(-33.91722, 151.23064),
mapTypeId: 'roadmap'
})
}
}
}
</script>
Where can I set
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=App.map" async defer></script>
The script element goes in your index.html file, for example:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=App.map" async defer></script>
</html>
If this doesnt work for you, try removing the callback from the end of the <script> element's src attribute as well as the async and defer keywords, so it looks like:
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey"></script>
Then in your vue instance, call your init() function once the App component has mounted. See below:
export default {
mounted () {
this.init()
},
methods: {
init () {
var map
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(-33.91722, 151.23064),
mapTypeId: 'roadmap'
})
}
}
}
I'd like to put the google map api just before </body>. Make sure your vue element is called before google map api (i.e. within app.js). Put initMap as the google api's callback.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app">
<map lat="1.23456" lng="100.21345"></map>
</div>
<script src="app.js"></script><!-- your vue element should be here -->
<script src="https://maps.googleapis.com/maps/api/js?key=YourKey&callback=initMap" async defer></script>
</body>
</html>
And this is my code in Map.vue, which has a definition of window.initMap(..). I also have a marker (pin) inside the map.
<template>
<div>
<div ref="map" style="width: 100%; height: 200px;"></div>
</div>
</template>
export default {
props: [
'lat',
'lng'
],
mounted() {
window.initMap = () => {
this.mapElement = new google.maps.Map(this.$refs.map, {
zoom: 14,
center: {lat: this.lat, lng: this.lng}
});
this.marker = new google.maps.Marker({
position: {lat: this.lat, lng: this.lng},
map: this.mapElement
});
}
},
data() {
return {
mapElement: null,
marker: null
}
}
}

Categories