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

SIG-1499 add map #684

Merged
merged 14 commits into from Mar 21, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
437 changes: 315 additions & 122 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Expand Up @@ -55,11 +55,13 @@
],
"dependencies": {
"@babel/polyfill": "^7.8.3",
"@datapunt/asc-assets": "^0.18.1",
"@datapunt/asc-core": "^0.18.1",
"@datapunt/asc-ui": "^0.18.2",
"@datapunt/amsterdam-react-maps": "git+https://github.com/Amsterdam/amsterdam-react-maps.git#feature/package-export",
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
"@datapunt/asc-assets": "0.18.2-alpha.29",
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
"@datapunt/asc-core": "0.18.1",
"@datapunt/asc-ui": "0.18.2-alpha.4",
"@datapunt/leaflet-geojson-bbox-layer": "0.1.1",
"@datapunt/matomo-tracker-js": "0.0.15",
"@datapunt/react-maps": "^0.7.2",
"@sentry/browser": "^5.13.0",
"abortcontroller-polyfill": "^1.4.0",
"amsterdam-amaps": "^2.0.0",
Expand Down
15 changes: 15 additions & 0 deletions src/components/BackgroundLayer/index.js
@@ -0,0 +1,15 @@
import React from 'react';
import { TileLayer } from '@datapunt/react-maps';

const BackgroundLayer = () => (
<TileLayer
args={['https://{s}.data.amsterdam.nl/topo_rd/{z}/{x}/{y}.png']}
options={{
subdomains: ['t1', 't2', 't3', 't4'],
tms: true,
attribution: 'Kaartgegevens CC-BY-4.0 Gemeente Amsterdam',
}}
/>
);

export default BackgroundLayer;
68 changes: 68 additions & 0 deletions src/components/MapEditor/index.js
@@ -0,0 +1,68 @@
import React, { memo , useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Map, Marker } from '@datapunt/react-maps';
import { ViewerContainer } from '@datapunt/asc-ui';
import { Zoom } from '@datapunt/amsterdam-react-maps/lib/components';
import styled from '@datapunt/asc-core';
import MAP_OPTIONS from 'shared/services/configuration/map-options';
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
import BackgroundLayer from 'components/BackgroundLayer';
import { markerIcon } from 'shared/services/configuration/map-markers';
import { feature2location } from 'shared/services/map-location';


const MapWrapper = styled.div`
position: relative;
`;

const StyledMap = styled(Map)`
width: 100%;
height: 450px;
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
`;

const StyledViewerContainer = styled(ViewerContainer)`
z-index: 400;
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
`;

const MapEditor = ({ location }) => {
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
const [marker, setMarker] = useState();

useEffect(() => {
if (!marker || !location.geometrie) return;

const opacity = 1;
const latlng = feature2location(location.geometrie);
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
marker.setLatLng(latlng);
marker.setOpacity(opacity);
// eslint-disable-next-line react-hooks/exhaustive-deps
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
}, [marker, location]);

return (
<MapWrapper>
<StyledMap options={MAP_OPTIONS}>
<StyledViewerContainer bottomRight={<Zoom />} />
<Marker
setInstance={setMarker}
args={[{
lat: 0,
lng: 0,
}]}
options={{
icon: markerIcon,
opacity: 0,
}}
/>
aditudorache marked this conversation as resolved.
Show resolved Hide resolved

<BackgroundLayer />
</StyledMap>
</MapWrapper>
);
};

MapEditor.propTypes = {
location: PropTypes.shape({
geometrie: PropTypes.shape({}),
address: PropTypes.shape({}),
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
}).isRequired,
};

export default memo(MapEditor);
14 changes: 14 additions & 0 deletions src/shared/services/configuration/map-markers.js
@@ -0,0 +1,14 @@
/* eslint-disable global-require */
import L from 'leaflet';

export const smallMarkerIcon = global.window.L.icon({
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
iconUrl: 'https://map.data.amsterdam.nl/dist/images/svg/marker.svg',
iconSize: [20, 20],
iconAnchor: [10, 19],
});

export const markerIcon = L.icon({
iconUrl: 'https://map.data.amsterdam.nl/dist/images/svg/marker.svg',
iconSize: [40, 40],
iconAnchor: [20, 39],
});
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
20 changes: 20 additions & 0 deletions src/shared/services/configuration/map-options.js
@@ -0,0 +1,20 @@
import { getCrsRd } from '@datapunt/amsterdam-react-maps/lib/utils';

export const DEFAULT_MARKER_POSITION = {
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
lat: 52.3731081,
lng: 4.8932945,
};


const MAP_OPTIONS = {
center: [52.3731081, 4.8932945],
zoomControl: false,
zoom: 10,
crs: getCrsRd(),
maxBounds: [
[52.25168, 4.64034],
[52.50536, 5.10737],
],
};

export default MAP_OPTIONS;
118 changes: 102 additions & 16 deletions src/shared/services/map-location/index.js
@@ -1,28 +1,114 @@
function mapLocation(loc) {
export const location2feature = location => ({
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
type: 'Point',
coordinates: [location.lng, location.lat],
});

export const feature2location = feature => {
const { coordinates } = feature;
return {
lat: coordinates[1],
lng: coordinates[0],
};
};

/**
* converts the sia location in latlon fromat
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
*/
export function mapLocation(loc) {
const location = {};

if (loc.dichtstbijzijnd_adres) {
location.address = { ...loc.dichtstbijzijnd_adres };
location.address.huisnummer = `${location.address.huisnummer}`;
location.address.huisnummer_toevoeging = `${location.address.huisnummer_toevoeging}`;
if (loc.geometrie) {
location.location = feature2location(loc.geometrie);
}

if (loc.buurt_code) {
location.buurtcode = loc.buurt_code;
}

if (loc.omgevingsinfo) {
location.buurt_code = loc.omgevingsinfo.buurtcode;
location.stadsdeel = loc.omgevingsinfo.stadsdeelcode;
if (loc.stadsdeelcode) {
location.stadsdeelcode = loc.stadsdeel;
}

if (loc.query) {
location.geometrie = {
type: 'Point',
coordinates: [
loc.query.longitude,
loc.query.latitude,
],
};
if (loc.address) {
location.address = address2pdok(loc.address);
}

return location;
}

export const pdok2address = pdokAddress => {
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
const {
straatnaam,
huisnummer,
huisletter,
huisnummertoevoeging,
postcode,
woonplaatsnaam,
} = pdokAddress;

return {
openbare_ruimte: straatnaam,
huisnummer: `${huisnummer}`,
huisletter: huisletter || '',
huisnummer_toevoeging: huisnummertoevoeging || '',
postcode,
woonplaats: woonplaatsnaam,
};
};

export const address2pdok = address => {
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
const {
openbare_ruimte,
huisnummer,
huisletter,
huisnummer_toevoeging,
postcode,
woonplaats,
} = address;

return {
straatnaam: openbare_ruimte,
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
huisnummer: `${huisnummer}`,
huisletter: huisletter || '',
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
huisnummertoevoeging: huisnummer_toevoeging || '',
postcode,
woonplaatsnaam: woonplaats,
};
};

/**
* converts the geocoder location in sia fromat
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
*/
export const getLocation = loc => {
const location = {};

if (loc.location) {
location.geometrie = location2feature(loc.location);
}

if (loc.buurtcode) {
location.buurt_code = loc.buurtcode;
}

if (loc.stadsdeel) {
location.stadsdeel = loc.stadsdeelcode;
}

if (loc.address) {
location.address = pdok2address(loc.address);
}

return location;
};

export const formatAddress = address => {
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
const toevoeging = address.huisnummer_toevoeging
? `-${address.huisnummer_toevoeging}`
: '';
const display = address.openbare_ruimte
? `${address.openbare_ruimte} ${address.huisnummer}${address.huisletter}${toevoeging}, ${address.postcode} ${address.woonplaats}`
: '_';
return display;
};

export default mapLocation;
16 changes: 12 additions & 4 deletions src/signals/incident/components/form/MapInput/index.js
Expand Up @@ -2,17 +2,25 @@ import React from 'react';
import PropTypes from 'prop-types';

import mapLocation from 'shared/services/map-location';
import MapInteractive from 'components/MapInteractive';
import MapEditor from 'components/MapEditor';

import Header from '../Header';
import { DEFAULT_MARKER_POSITION } from '../../../../../shared/services/configuration/map-options';
aditudorache marked this conversation as resolved.
Show resolved Hide resolved

const MapInput = ({
handler, touched, hasError, meta, parent, getError, validatorsOrOpts,
}) => {
const value = handler().value || {};
const value = handler().value || {
geometrie: {
type: "Point",
coordinates: [DEFAULT_MARKER_POSITION.lng, DEFAULT_MARKER_POSITION.lat],
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
}, address: {

},
};

/* istanbul ignore next */
const onQueryResult = d => {
const onLocationChange = d => {
parent.meta.updateIncident({ location: mapLocation(d) });
};

Expand All @@ -29,7 +37,7 @@ const MapInput = ({
getError={getError}
>
<div className="invoer">
<MapInteractive onQueryResult={onQueryResult} location={value} />
<MapEditor onLocationChange={onLocationChange} location={value} />
aditudorache marked this conversation as resolved.
Show resolved Hide resolved
</div>
</Header>
</div>
Expand Down