vue3-openlayers icon indicating copy to clipboard operation
vue3-openlayers copied to clipboard

Create ol-style-regular-shape for square points.

Open deguich opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe. I just wanted a square point but ol-style-regular-shape don't exists.

Describe the solution you'd like Add support of ol-style-regular-shape

Describe alternatives you've considered Using Icon.

Thx

deguich avatar Oct 30 '23 15:10 deguich

This is how I draw triangles:

  <ol-vector-layer :styles="cnrStyle" >

    <ol-source-vector :url="corners_url"
                      :format="geojson"
                       projection="EPSG:4326" />
  </ol-vector-layer>

and then:

import Style         from 'ol/style/Style';
import Stroke        from 'ol/style/Stroke';
import Fill          from 'ol/style/Fill';
import RegularShape  from 'ol/style/RegularShape';

function cnrStyle(feature) {

    return new Style({
      image: new RegularShape({
        fill   : new Fill(  {color: 'blue' }),
        stroke : new Stroke({color: 'black', width: 1}),
        points : 3,
        radius : 7
      })
    })
}

I hope this helps.

wendellwt avatar Nov 02 '23 18:11 wendellwt

Thx, it helps but could be good to have ol-style-regular-shape as a component.

I created this one but It is not a good solution :

  • raw copy of usePropsAsObjectProperties,
  • add setRadius function to the new RegularShapeStyle for render refresh,
  • provide regularShape as "cirlce"
<template>
  <slot></slot>
</template>

<script setup>
import RegularShapeStyle from "ol/style/RegularShape";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";

import {
  inject,
  watch,
  onMounted,
  onUnmounted,
  provide,
  computed,
  reactive,
  toRefs,
  ref
} from "vue";

function checkAndUpdateStylePropDef(options, key) {
  if (key === "styles") {
    options.style = ref(options[key].value);
  }
}

function usePropsAsObjectProperties(props, ignoredKeys = []) {
  const globalOptions = inject("ol-options");
  let options = toRefs(props);
  Object.keys(options).forEach((key) => {
    checkAndUpdateStylePropDef(options, key);
    options[key] = options[key].value;
  });
  const properties = reactive({ ...options });
  watch(props, () => {
    options = toRefs(props);
    Object.keys(options).forEach((key) => {
      if (properties[key] != options[key].value && !ignoredKeys.includes(key)) {
        checkAndUpdateStylePropDef(options, key);
        properties[key] = options[key].value;
      }
    });
  });
  if (globalOptions == null ? void 0 : globalOptions.debug) {
    console.debug("[Vue3-OpenLayers Debug] PROPS", {
      in: props,
      out: properties
    });
  }
  return {
    properties
  };
}

const props = defineProps({
  radius: {
    type: Number,
    default: undefined
  },
  points: {
    type: Number,
    required: true
  },
  scale: {
    type: Number,
    default: undefined
  },
  rotation: {
    type: Number,
    default: 0
  }
});

const style = inject("style", null);
const styledObj = inject("styledObj", null);

const { properties } = usePropsAsObjectProperties(props);

const createRegularShapeStyle = (innerProperties) => {
  const rss = new RegularShapeStyle({
    ...innerProperties,
    stroke: new Stroke({}),
    fill: new Fill()
  });
  rss.setRadius = function setRadius() {
    this.render();
  };
  return rss;
};

const regularShape = computed(() => createRegularShapeStyle(properties));

const applyStyle = () => {
  style?.value?.setImage(null);
  style?.value?.setImage(regularShape.value);
  styledObj?.value?.changed();
};
watch(properties, () => {
  applyStyle();
});

watch(
  () => style,
  () => {
    applyStyle();
  }
);

onMounted(() => {
  style?.value?.setImage(regularShape.value);
});

onUnmounted(() => {
  // @ts-ignore
  style?.value?.setImage(null);
});

provide("circle", regularShape);
provide("styledObj", styledObj);
</script>

deguich avatar Nov 07 '23 11:11 deguich