Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

admin-layereditor WFS attributes part 1 - geometry type #2356

Merged
14 changes: 13 additions & 1 deletion bundles/admin/admin-layereditor/resources/locale/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ Oskari.registerLocalization(
"globalWithStyles": "The layer has more than one style available in the service. However, the layer has been defined with a single default legend. Consider removing the current default legend to be able to use the style based legends."
}
},
"attributes": {
"label": "Attributes",
"geometryType": {
"label": "Geometry type",
"sourceAttributes": "Source: layer attributes",
"sourceCapabilities": "Source: layer capabilities",
"unknown":"Unknown",
"point": "Point",
"line": "Line",
"area":"Area",
"collection":"Collection"
}
},
"styles": {
"default": "Default style",
"desc": "Select a default style from the list. If there are several options, users can select a theme in the ‘Selected Layers’ menu.",
Expand Down Expand Up @@ -159,7 +172,6 @@ Oskari.registerLocalization(
"gfiTypeDesc": "Select a format for Get Feature Information (GFI). Possible formats are fetched automatically from the GetCapabilities response.",
"gfiStyle": "GFI style (XSLT)",
"gfiStyleDesc": "Define a style for Get Feature Information (GFI) as XSLT transformation.",
"attributes": "Attributes",
"clusteringDistance": "Point distance in cluster",
"forcedSRS": "Forced SRS",
"forcedSRSInfo": "View projections override compared to capabilities",
Expand Down
14 changes: 13 additions & 1 deletion bundles/admin/admin-layereditor/resources/locale/fi.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ Oskari.registerLocalization(
"globalWithStyles": "Tasolle on määritetty vain yksi yleinen oletuskarttaselite, vaikka sillä olisi rajapintapalvelusta useita tyylejä käytettävissä. Poista oletuskarttaselite ja määritä mahdolliset tyylikohtaiset karttaselitteet."
}
},
"attributes": {
"label": "Attribuutit",
"geometryType": {
"label": "Geometriatyyppi",
"sourceAttributes": "Lähde: tason attribuutit",
"sourceCapabilities": "Lähde: tason Capabilities-tiedot",
"unknown":"Ei tiedossa",
"point": "Piste",
"line": "Viiva",
"area":"Alue",
"collection":"Kaikki"
}
},
"styles": {
"default": "Oletustyyli",
"desc": "Taso lisätään kartalle oletustyylillä. Käyttäjä voi vaihtaa tyyliä ”Valitut tasot”-valikon kautta.",
Expand Down Expand Up @@ -160,7 +173,6 @@ Oskari.registerLocalization(
"gfiTypeDesc": "Valitse listalta formaatti, jossa kohdetiedot (GFI) haetaan. Mahdolliset formaatit on määritelty WMS-palvelun GetCapabilities-vastausviestissä.",
"gfiStyle": "GFI-tyyli (XSLT)",
"gfiStyleDesc": "Määrittele kohdetietojen esitystapa XSLT-muunnoksen avulla.",
"attributes": "Attribuutit",
"clusteringDistance": "Pisteiden etäisyys klusteroidessa",
"forcedSRS": "Pakotetut projektiot",
"forcedSRSInfo": "Pakotetut projektiot verrattuna GetCapabilites-määritykseen",
Expand Down
14 changes: 13 additions & 1 deletion bundles/admin/admin-layereditor/resources/locale/sv.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ Oskari.registerLocalization(
"globalWithStyles": "Till kartlagret har endast en standard teckenförklaring fastställts, men det finns ytterliga stilar med förklaringar tillgängliga på gränssnittet. Du kan ta bort standardvalet för att kunna utnyttja dessa."
}
},
"attributes": {
"label": "Attribut",
"geometryType": {
"label": "Typ av geometri",
"sourceAttributes": "Källa: kartlagrets attribut",
"sourceCapabilities": "Källa: kartlagrets capabilities",
"unknown":"Okänd",
"point": "Punkten",
"line": "Linje",
"area":"Området",
"collection":"All"
}
},
"styles": {
"default": "Förvald utseende",
"desc": "Välj en standardstil från listan. Om det finns flera alternativ kan användare välja ett tema i menyn 'Valda lager'.",
Expand Down Expand Up @@ -157,7 +170,6 @@ Oskari.registerLocalization(
"gfiTypeDesc": "Svarets typ dvs Get Feature Info (GFI)",
"gfiStyle": "GFI stil",
"gfiStyleDesc": "GFI stil (XSLT)",
"attributes": "Attribut",
"clusteringDistance": "Punktavstånd i kluster",
"forcedSRS": "Tvingade SRS",
"forcedSRSInfo": "Tvångs SRS jämfört med GetCapabilites",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GfiType } from './GfiType';
import { GfiContent } from './GfiContent';
import { GfiStyle } from './GfiStyle';
import { Attributes } from './Attributes';
import { VectorLayerAttributes } from './VectorLayerAttributes';
import { Attributions } from './Attributions';
import { MetadataId } from './MetadataId';
import { Capabilities } from './Capabilities';
Expand All @@ -24,7 +25,8 @@ const {
GFI_TYPE,
GFI_XSLT,
ATTRIBUTIONS,
ATTRIBUTES
ATTRIBUTES,
VECTOR_LAYER
} = LayerComposingModel;

export const AdditionalTabPane = ({ layer, propertyFields, metadata, controller }) => {
Expand Down Expand Up @@ -62,6 +64,9 @@ export const AdditionalTabPane = ({ layer, propertyFields, metadata, controller
{ isQueryable && propertyFields.includes(GFI_XSLT) &&
<GfiStyle layer={layer} controller={controller} />
}
{ propertyFields.includes(VECTOR_LAYER) &&
<VectorLayerAttributes layer={layer} controller={controller} />
}
{ propertyFields.includes(ATTRIBUTES) &&
<Attributes layer={layer} controller={controller} />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const Attributes = ({ layer, controller }) => {
}
return (
<Fragment>
<Message messageKey='attributes'/>
<Message messageKey='attributes.label'/>
{ !isValid && <AttributeInfo attributes={layer.attributes} /> }
<StyledFormField>
<JsonInput
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Message, Select, Option } from 'oskari-ui';
import { Controller } from 'oskari-ui/util';
import { StyledFormField } from '../styled';
import { GEOMETRY_TYPES, getGeometryType } from '../../LayerHelper';
import { InfoTooltip } from '../InfoTooltip';

export const VectorLayerAttributes = ({ layer, controller }) => {
const geometryTypeSource = layer.attributes.data?.geometryType ? 'Attributes' : 'Capabilities';
const onGeometryTypeChange = value => {
if (GEOMETRY_TYPES[0] === value) {
controller.setAttributesData('geometryType');
} else {
controller.setAttributesData('geometryType', value);
}
};
return (
<Fragment>
<Message messageKey='attributes.geometryType.label'/>
<InfoTooltip messageKeys={`attributes.geometryType.source${geometryTypeSource}`}/>
<StyledFormField>
<Select
value={getGeometryType(layer)}
onChange={onGeometryTypeChange}>
{ GEOMETRY_TYPES.map(type => (
<Option key={type} value={type}>
<Message messageKey={`attributes.geometryType.${type}`} />
</Option>
)) }
</Select>
</StyledFormField>
</Fragment>
);
};

VectorLayerAttributes.propTypes = {
layer: PropTypes.object.isRequired,
controller: PropTypes.instanceOf(Controller).isRequired
};
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,17 @@ class UIHandler extends StateHandler {
this.updateLayerAttributes(attributes, layer);
}

setAttributesData (key, value) {
const layer = { ...this.getState().layer };
const { data = {} } = layer.attributes || {};
if (typeof value === 'undefined') {
delete data[key];
} else {
data[key] = value;
}
this.updateLayerAttributes({ ...layer.attributes, data }, layer);
}

setLocalizedNames (locale) {
this.updateState({
layer: { ...this.getState().layer, locale }
Expand Down Expand Up @@ -452,7 +463,7 @@ class UIHandler extends StateHandler {
}

// Delete missing attibute keys but keep managed attributes
const managedAttributes = ['forcedSRS'];
const managedAttributes = ['forcedSRS', 'data'];
Object.keys(layer.attributes)
.filter(key => !managedAttributes.includes(key))
.forEach(key => delete layer.attributes[key]);
Expand Down Expand Up @@ -1190,6 +1201,7 @@ const wrapped = controllerMixin(UIHandler, [
'removeVectorStyleFromLayer',
'saveVectorStyleToLayer',
'setAttributes',
'setAttributesData',
'setAttributionsJSON',
'setCapabilitiesUpdateRate',
'setClusteringDistance',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { StyleEditor } from 'oskari-ui/components/StyleEditor';
import styled from 'styled-components';
import { ThemeConsumer } from 'oskari-ui/util';
import { generateBlankStyle } from 'oskari-ui/components/StyleEditor/index';
import { SUPPORTED_FORMATS } from 'oskari-ui/components/StyleEditor/constants';
import { getGeometryType } from '../../LayerHelper';

const FullWidthSpace = styled(Space)`
& {
Expand Down Expand Up @@ -109,6 +111,8 @@ export const VectorStyle = ThemeConsumer(LocaleConsumer(({ theme = {}, layer, ge
};
const visible = !!state.modal;
const externalType = external ? getExternalStyleType(layer) : null;
const geometryType = getGeometryType(layer);
const styleTabs = SUPPORTED_FORMATS.includes(geometryType) ? [geometryType] : SUPPORTED_FORMATS;
return (
<FullWidthSpace direction='vertical'>
<Space direction='horizontal'>
Expand Down Expand Up @@ -153,6 +157,7 @@ export const VectorStyle = ThemeConsumer(LocaleConsumer(({ theme = {}, layer, ge
{ state.modal === 'editor' &&
<StyleEditor
oskariStyle={ state.style.featureStyle }
tabs={styleTabs}
onChange={ (featureStyle) => updateStyle({ featureStyle })}
/>
}
Expand Down
17 changes: 17 additions & 0 deletions bundles/admin/admin-layereditor/view/LayerHelper.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
export const GEOMETRY_TYPES = ['unknown', 'point', 'line', 'area', 'collection'];
const AREA_TYPES = ['surface', 'polygon'];

export const getGeometryType = layer => {
const { attributes, capabilities } = layer;
if (attributes?.data?.geometryType) {
return attributes.data.geometryType;
}
const { geomName, featureProperties = [] } = capabilities;
const capaType = featureProperties.find(prop => prop.name === geomName)?.type.toLowerCase() || '';
// SurfacePropertyType, GeometryPropertyType, PointPropertyType, MultiLineStringPropertyType, MultiPolygon,...
if (AREA_TYPES.find(type => capaType.includes(type))) {
return 'area';
}
return GEOMETRY_TYPES.find(type => capaType.includes(type)) || 'unknown';
};

// keys are the server side expected keys and values are the keys used by frontend
const APIMapping = {
dataprovider_id: 'dataProviderId',
Expand Down
3 changes: 2 additions & 1 deletion bundles/mapping/mapmodule/domain/LayerComposingModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const PROPERTY_FIELDS = [
'URL',
'VERSION',
'WFS_RENDER_MODE',
'DECLUTTER'
'DECLUTTER',
'VECTOR_LAYER'
];

// Common fields are enforced on composing model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class VectorTileLayerPlugin extends AbstractVectorLayerPlugin {
LayerComposingModel.VECTOR_STYLES,
LayerComposingModel.TILE_GRID,
LayerComposingModel.URL,
LayerComposingModel.DECLUTTER
LayerComposingModel.DECLUTTER,
LayerComposingModel.VECTOR_LAYER
], null, [LayerComposingModel.NAME]); // common field name is not used in vectortilelayers so it is skipped on LayerComposingModel

mapLayerService.registerLayerModel(this.layertype + 'layer', this._getLayerModelClass(), composingModel);
Expand Down
3 changes: 2 additions & 1 deletion bundles/mapping/mapwfs2/plugin/WfsVectorLayerPlugin.ol.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ export class WfsVectorLayerPlugin extends AbstractVectorLayerPlugin {
LayerComposingModel.VECTOR_STYLES,
LayerComposingModel.URL,
LayerComposingModel.VERSION,
LayerComposingModel.WFS_RENDER_MODE
LayerComposingModel.WFS_RENDER_MODE,
LayerComposingModel.VECTOR_LAYER
], ['1.1.0', '2.0.0', '3.0.0']);

const layerClass = 'Oskari.mapframework.bundle.mapwfs2.domain.WFSLayer';
Expand Down
3 changes: 2 additions & 1 deletion bundles/mapping/tiles3d/plugin/Tiles3DLayerPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Oskari.clazz.define('Oskari.mapframework.mapmodule.Tiles3DLayerPlugin',
LayerComposingModel.SRS,
LayerComposingModel.VECTOR_STYLES,
LayerComposingModel.EXTERNAL_VECTOR_STYLES,
LayerComposingModel.URL
LayerComposingModel.URL,
LayerComposingModel.VECTOR_LAYER
]);
mapLayerService.registerLayerModel(registerType, clazz, composingModel);
mapLayerService.registerLayerModelBuilder(registerType, new Tiles3DModelBuilder());
Expand Down