Skip to content

Demo

This Demo show lot's of the provided features. However, to try out features, check out the Playground.

7
  • OSM

  • JAWG

  • AIRPORTS

  • STAR

  • CLUSTER

 
200 km
  • Center map here
  • Add a Marker

  • Zoom In
  • Zoom Out

France

Turkey

Germany

vue
<template>  <ol-map  ref="map"  :loadTilesWhileAnimating="true"  :loadTilesWhileInteracting="true"  style="height: 600px"  >  <ol-view  ref="view"  :center="center"  :rotation="rotation"  :zoom="zoom"  :projection="projection"  />   <ol-swipe-control  v-if="layerList.length > 0"  :layers="[layerList[0]]"  :right-layers="[layerList[1]]"  />   <ol-layer-switcher-image-control />   <ol-zone-control  :zones="zones"  :projection="projection"  :layer="jawgLayer.tileLayer"  v-if="jawgLayer != null"  >  </ol-zone-control>   <ol-tile-layer ref="osmLayer" title="OSM">  <ol-source-osm />  </ol-tile-layer>   <ol-tile-layer ref="jawgLayer" title="JAWG">  <ol-source-xyz  crossOrigin="anonymous"  url="https://c.tile.jawg.io/jawg-dark/{z}/{x}/{y}.png?access-token=87PWIbRaZAGNmYDjlYsLkeTVJpQeCfl2Y61mcHopxXqSdxXExoTLEv7dwqBwSWuJ"  />  </ol-tile-layer>   <ol-control-bar>  <ol-toggle-control  html="🔘"  className="edit"  title="Point"  :onToggle="(active) => changeDrawType(active, 'Point')"  />  <ol-toggle-control  html="🔹"  className="edit"  title="Polygon"  :onToggle="(active) => changeDrawType(active, 'Polygon')"  />  <ol-toggle-control  html="🟢"  className="edit"  title="Circle"  :onToggle="(active) => changeDrawType(active, 'Circle')"  />  <ol-toggle-control  html="〰️"  className="edit"  title="LineString"  :onToggle="(active) => changeDrawType(active, 'LineString')"  />  <ol-video-recorder-control @stop="videoStopped" />  <ol-print-dialog-control />  </ol-control-bar>   <ol-mouse-position-control />  <ol-full-screen-control />  <ol-overview-map-control>  <ol-tile-layer>  <ol-source-osm />  </ol-tile-layer>  </ol-overview-map-control>   <ol-scale-line-control />  <ol-rotate-control />  <ol-zoom-control />  <ol-zoom-slider-control />  <ol-zoom-to-extent-control  :extent="[23.906, 42.812, 46.934, 34.597]"  tipLabel="Fit to Turkey"  />   <ol-context-menu-control :items="contextMenuItems" />   <ol-interaction-cluster-select @select="featureSelected" :pointRadius="20">  <ol-style>  <ol-style-stroke color="green" :width="5"></ol-style-stroke>  <ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>  <ol-style-icon :src="markerIcon" :scale="0.05"></ol-style-icon>  </ol-style>  </ol-interaction-cluster-select>   <ol-interaction-select  @select="featureSelected"  :condition="selectCondition"  :filter="selectInteactionFilter"  v-if="!drawEnable"  >  <ol-style>  <ol-style-stroke color="green" :width="10"></ol-style-stroke>  <ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>  <ol-style-icon :src="markerIcon" :scale="0.05"></ol-style-icon>  </ol-style>  </ol-interaction-select>   <ol-vector-layer  title="AIRPORTS"  preview="https://raw.githubusercontent.com/MelihAltintas/vue3-openlayers/main/src/assets/tr.png"  >  <ol-source-vector  ref="cities"  url="https://raw.githubusercontent.com/alpers/Turkey-Maps-GeoJSON/master/tr-cities-airports.json"  :format="geoJson"  :projection="projection"  >  <ol-interaction-modify  v-if="drawEnable"  @modifyend="modifyend"  @modifystart="modifystart"  >  </ol-interaction-modify>   <ol-interaction-draw  v-if="drawEnable"  :type="drawType"  @drawend="drawend"  @drawstart="drawstart"  >  </ol-interaction-draw>   <ol-interaction-snap v-if="drawEnable" />  </ol-source-vector>   <ol-style>  <ol-style-stroke color="red" :width="2"></ol-style-stroke>  <ol-style-fill color="rgba(255,255,255,0.1)"></ol-style-fill>  <ol-style-circle :radius="7">  <ol-style-fill color="blue"></ol-style-fill>  </ol-style-circle>  </ol-style>  </ol-vector-layer>   <ol-vector-layer  :updateWhileAnimating="true"  :updateWhileInteracting="true"  title="STAR"  preview="https://raw.githubusercontent.com/MelihAltintas/vue3-openlayers/main/src/assets/star.png"  >  <ol-source-vector ref="vectorsource">  <ol-animation-shake :duration="2000" :repeat="5">  <ol-feature v-for="index in 20" :key="index">  <ol-geom-point  :coordinates="arrayWith500Points[index - 1]"  ></ol-geom-point>   <ol-style>  <ol-style-icon :src="starIcon" :scale="0.1"></ol-style-icon>  </ol-style>  </ol-feature>  </ol-animation-shake>  <ol-feature>  <ol-geom-circle :center="[38, 42]" :radius="2"></ol-geom-circle>  <ol-style>  <ol-style-stroke color="blue" :width="2"></ol-style-stroke>  <ol-style-fill color="rgba(255,200,0,0.2)"></ol-style-fill>  </ol-style>  </ol-feature>  </ol-source-vector>  </ol-vector-layer>   <ol-animated-cluster-layer  :animationDuration="500"  :distance="40"  title="CLUSTER"  preview="https://raw.githubusercontent.com/MelihAltintas/vue3-openlayers/main/src/assets/cluster.png"  >  <ol-source-vector ref="vectorsource">  <ol-feature v-for="index in 300" :key="index">  <ol-geom-point  :coordinates="arrayWith500Points[index - 1]"  ></ol-geom-point>  </ol-feature>  </ol-source-vector>   <ol-style :overrideStyleFunction="overrideStyleFunction">  <ol-style-stroke color="red" :width="2"></ol-style-stroke>  <ol-style-fill color="rgba(255,255,255,0.1)"></ol-style-fill>   <ol-style-circle :radius="20">  <ol-style-stroke  color="black"  :width="15"  :lineDash="[]"  lineCap="butt"  ></ol-style-stroke>  <ol-style-fill color="black"></ol-style-fill>  </ol-style-circle>   <ol-style-text>  <ol-style-fill color="white"></ol-style-fill>  </ol-style-text>  </ol-style>  </ol-animated-cluster-layer>   <ol-graticule-layer  :show-labels="true"  :wrap-x="false"  :stroke-style="graticuleStyle"  >  </ol-graticule-layer>   <ol-overlay  :position="selectedCityPosition"  v-if="selectedCityName != '' && !drawEnable"  >  <template v-slot="slotProps">  <div class="overlay-content">  {{ selectedCityName }} {{ slotProps }}  </div>  </template>  </ol-overlay>   <ol-vector-layer>  <ol-source-vector>  <ol-feature ref="animationPath">  <ol-geom-line-string :coordinates="path"></ol-geom-line-string>  <ol-style-flow-line  color="red"  color2="yellow"  :width="10"  :width2="10"  :arrow="1"  />  </ol-feature>  <ol-animation-path  v-if="animationPath"  :path="animationPath.feature"  :duration="4000"  :repeat="10"  >  <ol-feature>  <ol-geom-point :coordinates="path[0]"></ol-geom-point>  <ol-style>  <ol-style-circle :radius="10">  <ol-style-fill color="blue"></ol-style-fill>  <ol-style-stroke color="blue" :width="2"></ol-style-stroke>  </ol-style-circle>  </ol-style>  </ol-feature>  </ol-animation-path>  </ol-source-vector>  </ol-vector-layer>  </ol-map> </template>  <script setup lang="ts"> import { ref, inject, onMounted } from "vue";  import markerIcon from "@/assets/marker.png"; import starIcon from "@/assets/star.png"; import { arrayWith500Points } from "./points"; import { Stroke } from "ol/style";  const center = ref([34, 39.13]); const projection = ref("EPSG:4326"); const zoom = ref(6); const rotation = ref(0);  const format = inject("ol-format");  const geoJson = new format.GeoJSON();  const selectConditions = inject("ol-selectconditions");  const selectCondition = selectConditions.pointerMove;  const selectedCityName = ref(""); const selectedCityPosition = ref([]);  const extent = inject("ol-extent");  const Feature = inject("ol-feature"); const Geom = inject("ol-geom");  const contextMenuItems = ref([]); const vectorsource = ref(null); const view = ref(null);  const drawEnable = ref(false); const drawType = ref("Point");  const changeDrawType = (active, draw) => {  drawEnable.value = active;  drawType.value = draw; };  contextMenuItems.value = [  {  text: "Center map here",  classname: "some-style-class", // add some CSS rules  callback: (val) => {  view.value.setCenter(val.coordinate);  }, // `center` is your callback function  },  {  text: "Add a Marker",  classname: "some-style-class", // you can add this icon with a CSS class  // instead of `icon` property (see next line)  icon: markerIcon, // this can be relative or absolute  callback: (val) => {  console.log(val);  const feature = new Feature({  geometry: new Geom.Point(val.coordinate),  });  vectorsource.value.source.addFeature(feature);  },  },  "-", // this is a separator ];  const graticuleStyle = new Stroke({  color: "rgba(255,120,0,0.9)",  width: 1,  lineDash: [0.5, 4], });  const featureSelected = (event) => {  if (event.selected.length == 1) {  selectedCityPosition.value = extent.getCenter(  event.selected[0].getGeometry().extent_,  );  selectedCityName.value = event.selected[0].values_.name;  } else {  selectedCityName.value = "";  } };  const overrideStyleFunction = (feature, style) => {  const clusteredFeatures = feature.get("features");  const size = clusteredFeatures.length;   const color = size > 20 ? "192,0,0" : size > 8 ? "255,128,0" : "0,128,0";  const radius = Math.max(8, Math.min(size, 20));  const dash = (2 * Math.PI * radius) / 6;  const calculatedDash = [0, dash, dash, dash, dash, dash, dash];   style.getImage().getStroke().setLineDash(dash);  style  .getImage()  .getStroke()  .setColor("rgba(" + color + ",0.5)");  style.getImage().getStroke().setLineDash(calculatedDash);  style  .getImage()  .getFill()  .setColor("rgba(" + color + ",1)");   style.getImage().setRadius(radius);   style.getText().setText(size.toString());  return style; };  const selectInteactionFilter = (feature) => {  return feature.values_.name != undefined; };  const drawstart = (event) => {  console.log(event); };  const drawend = (event) => {  console.log(event); };  const modifystart = (event) => {  console.log(event); };  const modifyend = (event) => {  console.log(event); };  const videoStopped = (event) => {  console.log(event); };  const jawgLayer = ref(null); const osmLayer = ref(null); const layerList = ref([]); onMounted(() => {  layerList.value.push(jawgLayer.value.tileLayer);  layerList.value.push(osmLayer.value.tileLayer);  console.log(layerList.value); });  const path = ref([  [25.6064453125, 44.73302734375001],  [27.759765625, 44.75500000000001],  [28.287109375, 43.32677734375001],  [30.55029296875, 46.40294921875001],  [31.69287109375, 43.04113281250001], ]); const animationPath = ref(null);  const zones = [  {  title: "France",  extent: [  -5.318421740712579, 41.16082274292913, 9.73284186155716,  51.21957336557702,  ],  },  {  title: "Turkey",  extent: [22.473435, 34.465842, 43.40239, 42.56525],  },  {  title: "Germany",  extent: [-0.101752, 47.49888, 20.827203, 54.043465],  }, ]; </script>  <style scoped> .overlay-content {  background: #c84031;  color: white;  box-shadow: 0 5px 10px rgb(2 2 2 / 20%);  padding: 10px 20px;  font-size: 16px; } </style>