npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@polar/plugin-gfi

v2.0.0

Published

Gfi plugin for POLAR that adds feature information retrieval. UI elements can be provided by configuration, else it works as a store integration.

Downloads

712

Readme

GFI

Scope

The GFI plugin can be used to fetch and optionally display GFI (GetFeatureInfo) from WMS and WFS services as well as layers based on GeoJSON files. In a first step, the information is stored in the VueX store to allow for easy access. Display is optional and quite obstructive within the map client.

⚠️ The display feature is currently not meant for production. Please use data bindings for display to avoid obstructing the map client.

Configuration

gfi

| fieldName | type | description | | - | - | - | | coordinateSources | string[] | The GFI plugin will react to these coordinate positions in the store. This allows it to react to e.g. the address search of the pins plugin. Please see example configuration for the common use-cases. Please mind that, when referencing another plugin, that plugin must be in addPlugins before this one. | | layers | Record<string, gfiLayerConfiguration> | Maps a string (must be a layer ID) to a behaviour configuration for that layer. | | activeLayerPath | string? | Optional store path to array of active mask layer ids. If used with LayerChooser, setting this to 'plugin/layerChooser/activeMaskIds' will result in an info text in the GFI box, should no layer be active. If used without LayerChooser, the active mask layers have to be provided by another plugin or the client. If not set, the GFI plugin may e.g. show an empty list, which may be confusing to some users. | | afterLoadFunction | function (featuresByLayerId: Record<string, GeoJsonFeature[]>): Record<layerId, GeoJsonFeature[]>? | This method can be used to extend, filter, or otherwise modify a GFI result. | | boxSelect | boolean? | If set to true, multiple features can be selected at once by using the modifier key (CTRL on Windows or Command on macOS) and dragging the mouse. Similar to gfi.directSelect, features can be added and removed by selection / unselecting them. The features need to be distinguishable by their properties for the functionality to properly work. Does not work together with extendedMasterportalapiMarkers of @polar/core. Defaults to false. | | customHighlightStyle | customHighlighStyle? | If required a user can change the stroke and fill of the highlighted feature. The default style as seen in the example will be used for each part that is not customized. An empty object will return the complete default style while e.g. for an object without a configured fill the default fill will be applied. | | directSelect | boolean? | If set to true, a feature can be selected without defining a value in gfi.coordinateSources. It is also possible to add multiple features to the selection by using the modifier key (CTRL on Windows or Command on macOS). To delesect a feature, simply reclick it with the modifier key pressed. To create a new selection, click anywhere else without pressing the modifier key. Be careful when using this parameter together with some values set in coordinateSources as it may lead to unexpected results. The features need to be distinguishable by their properties for the functionality to properly work. Does not work together with extendedMasterportalapiMarkers of @polar/core. Defaults to false. | | featureList | featureList? | If defined, a list of available vector layer features is visible when no feature is selected. Only usable if renderType is set to iconMenu and window is set to true for at least one configured layer. | | gfiContentComponent | VueConstructor? | Allows overriding the GfiContent.vue component for custom design and functionality. Coding knowledge is required to use this feature, as any implementation will have to rely upon the VueX store model. Please refer to the implementation. | | maxFeatures | number? | Limits the viewable GFIs per layer by this number. The first n elements are chosen arbitrarily. Useful if you e.g. just want one result, or to limit an endless stream of returns to e.g. 10. Infinite by default. | | mode | enum["bboxDot", "intersects"]? | Method of calculating which feature has been chosen by the user. bboxDot utilizes the bbox-url parameter using the clicked coordinate while intersects uses a Filter to calculate the intersected features. Layers can have their own gfiMode parameter which would override this global mode. To apply this, add the desired value to the parameter in the mapConfiguration. Defaults to 'bboxDot'. | | renderType | ('iconMenu' | 'independent')? | Only relevant if window is set to true for at least one layer. Whether the gfi plugin is rendered independently or as part of the IconMenu. Defaults to 'independent'. |

For details on the displayComponent attribute, refer to the Global Plugin Parameters section of @polar/core.

import Component from '.component/vue'

gfi: {
  mode: 'bboxDot',
  activeLayerPath: 'plugin/layerChooser/activeMaskIds',
  afterLoadFunction: afterLoadFunction,
  layers: {
    'layerId': {
      geometry: true,
      window: true,
      maxFeatures: 10,
      geometryName: 'app:geometry',
      exportProperty: 'Export',
    },
  },
  coordinateSources: [
    'plugin/pins/transformedCoordinate',
    'plugin/pins/coordinatesAfterDrag',
  ],
  customHighlightStyle: {
    stroke: {
      color: '#FFFF00',
      width: 3,
    },
    fill: {
      color: 'rgb(255, 255, 255, 0.7)',
    },
  },
  gfiContentComponent: Component,
}

function afterLoadFunction(featuresByLayerId: Record<string, GeoJsonFeature[]>): Record<string, GeoJsonFeature[]> {
  const filteredFeaturesByLayerId: Record<string, GeoJsonFeature[]> = {};

  for (const layerId in featuresByLayerId) {
    if (featuresByLayerId.hasOwnProperty(layerId)) {
      const features = featuresByLayerId[layerId];
      filteredFeaturesByLayerId[layerId] = features.filter(feature => feature.properties.type === 'desiredType');
    }
  }

  return filteredFeaturesByLayerId;
}
gfi.gfiLayerConfiguration

| fieldName | type | description | | - | - | - | | exportProperty | string? | Property of the features of a service having an url usable to trigger a download of features as a document. | | geometry | boolean? | If true, feature geometry will be highlighted within the map. Defaults to false. | | geometryName | string? | Name of the geometry property if not the default field. | | isSelectable | ((feature: GeoJsonFeature) => boolean)? | A function can be defined to allow filtering features to be either selectable (return true) or not. Unselectable features will be filtered out by the GFI plugin and have neither GFI display nor store presence, but may be visible in the map nonetheless, depending on your other configuration. Please also mind that usage in combination with extendedMasterportalapiMarkers requires further configuration of that feature for smooth UX; see the respective documentation of @polar/core. | | properties | Record<propertyName, displayName>/string[]? | In case window is true, this will be used to determine which contents to show. In case of an array, keys are used to select properties. In case of an object, keys are used to select properties, but will be titles as their respective values. Displays all properties by default. | | showTooltip | ((feature: Feature) => [string, string][])? | If given, a tooltip will be shown with the values calculated for the feature. The first string is the HTML tag to render, the second its contents; contants may be locale keys. For more information regarding the strings, see the documentation of the @polar/lib-tooltip package. Defaults to undefined. Please mind that tooltips will only be shown if a mouse is used or the hovering device could not be detected. Touch and pen interactions do not open tooltips since they will open the GFI window, rendering the gatherable information redundant. | | window | boolean? | If true, properties will be shown in the map client. Defaults to false. |

Example configuration:

layers: {
  'layerId': {
    geometry: true,
    window: true,
    maxFeatures: 10,
    geometryName: 'app:geometry',
    exportProperty: 'Export',
    properties: {
      status: 'status',
      type: 'type',
    },
    showTooltip: (feature: Feature): [string, string][] => {
      return [
        ['div', `Feature ID: ${feature.properties.id}`],
        ['span', `Coordinates: ${feature.geometry.coordinates.join(', ')}`]
      ];
    },
    isSelectable: (feature: Feature): boolean => Boolean(Math.random() < 0.5)
  },
}

Additionally, if using a WMS service, the following properties can be configured as well.

| fieldName | type | description | | - | - | - | | filterBy | 'clickPosition'? | Some WMS services may return features close to the clicked position. By setting the value clickPosition, only features that intersect the clicked position are shown to the user. Defaults to showing all features. | | format | 'GML' | 'GML2' | 'GML3' | 'GML32' | 'text'? | If the infoFormat is not set to 'application/geojson'´, this can be configured to be the known file format of the response. If not given, the format is parsed from the response data. |

Example configuration:

layers: {
  'layerId': {
    geometry: true,
    window: true,
    maxFeatures: 10,
    geometryName: 'app:geometry',
    filterBy: 'clickPosition'
    format: 'text'
  },
}
gfi.customHighlightStyle

| fieldName | type | description | | - | - | - | | fill | ol/style/Fill? | Object for defining the fill style. See OpenLayers documentation for full options. | | stroke | ol/style/Stroke? | Object for defining the stroke style. See OpenLayers documentation for full options. |

Example configuration:

customHighlightStyle: {
  stroke: {
    color: '#FFFF00',
    width: 3,
  },
  fill: {
    color: 'rgb(255, 255, 255, 0.7)',
  },
},
gfi.featureList

| fieldName | type | description | | - | - | - | | mode | 'visible' | 'loaded' | Whether to show only features currently visible in the map view's bounding box or to display all loaded features. In the latter case, if you desire to display all features of a layer (seen or not), set its loading strategy to 'all'. | | bindWithCoreHoverSelect | boolean? | If true, the hover/select fields in the core's state will be listened to and interacted with. This will result in a bilateral hovering and selecting of features with the core. Defaults to false. | | pageLength | number? | A number >0 that sets the limit to the feature list's length. If the length is surpassed, additional features can be reached by using the pagination that is generated in such a case. If not defined, the list can be of arbitrary length. | | text | (function | string)[]? | Array of one to three entries that will produce title, subtitle, and an additional subtitle for the list view. If string, the text item will simply be that feature's value for the denoted property. If function, it's assumed to match the function signature (feature: OpenLayersFeature): string, and the returned string will be used for the text item. |

Example configuration:

featureList: {
  mode: 'visible',
  bindWithCoreHoverSelect: true,
  pageLength: 5,
  text: ['Nature reserves', (feature) => `${feature.get('str')} ${feature.get('hsnr')}`]
}

Store

State

If a successful query has been sent and a response has been received, the result will be saved in the store and can be subscribed through the path 'plugin/gfi/featureInformation'. If, however, a query for a layer fails, a Symbol containing the error will be saved in the store instead to indicate the error.

The exact value of featureInformation may vary wildly depending on the service used, but is always given as json representation here.

map.subscribe('plugin/gfi/featureInformation', (featureInformation) => {
  /* Your code here */
})