Skip to content

Commit

Permalink
[Feat] support create geojson path from point csv in polygon layer
Browse files Browse the repository at this point in the history
Signed-off-by: Ihor Dykhta <dikhta.igor@gmail.com>
  • Loading branch information
igorDykhta committed Sep 23, 2024
1 parent b4cec94 commit b8b26a8
Show file tree
Hide file tree
Showing 29 changed files with 941 additions and 242 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/d3-array": "^2.0.0",
"@types/d3-scale": "^3.2.2",
"@types/geojson": "^7946.0.7",
"@types/geojson": "^7946.0.8",
"@types/jsdom": "^21.1.1",
"@types/redux-actions": "^2.6.2",
"@types/supercluster": "^7.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function getValidFieldPairsSuggestionsForColumn(
LayerColumnConfigFactory.deps = [ColumnSelectorFactory];

function LayerColumnConfigFactory(ColumnSelector: ReturnType<typeof ColumnSelectorFactory>) {
const LayerColumnConfig: React.FC<LayerColumnConfigProps<MinimalField>> = ({
const LayerColumnConfig: React.FC<LayerColumnConfigProps<MinimalField & {fieldIdx: number}>> = ({
columnPairs,
fieldPairs,
columns,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ const ConfigPanesContainer = styled.div`
}
`;

interface FieldOption extends MinimalField {}
interface FieldOption extends MinimalField {
fieldIdx: number;
}

export type ColumnModeConfigProps = {
supportedColumnModes: SupportedColumnMode[] | null;
Expand Down Expand Up @@ -237,9 +239,7 @@ function LayerColumnModeConfigFactory(
columnPairs={layer.columnPairs}
columns={cols}
assignColumnPairs={layer.assignColumnPairs.bind(layer)}
assignColumn={
layer.assignColumn.bind(layer) as (key: string, field: FieldOption) => LayerColumns
}
assignColumn={layer.assignColumn.bind(layer)}
columnLabels={layer.columnLabels}
fields={fields}
fieldPairs={fieldPairs}
Expand Down
2 changes: 1 addition & 1 deletion src/deckgl-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@mapbox/geo-viewport": "^0.4.1",
"@mapbox/vector-tile": "^1.3.1",
"@types/d3-array": "^2.0.0",
"@types/geojson": "^7946.0.7",
"@types/geojson": "^7946.0.8",
"@types/lodash.memoize": "^4.1.7",
"@types/supercluster": "^7.1.0",
"d3-array": "^2.8.0",
Expand Down
2 changes: 1 addition & 1 deletion src/layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@turf/boolean-within": "^6.0.1",
"@turf/center": "^6.0.1",
"@turf/helpers": "^6.1.4",
"@types/geojson": "^7946.0.7",
"@types/geojson": "^7946.0.8",
"@types/keymirror": "^0.1.1",
"@types/lodash.memoize": "^4.1.7",
"@types/lodash.uniq": "^4.5.7",
Expand Down
46 changes: 28 additions & 18 deletions src/layers/src/base-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
hexToRgb,
getLatLngBounds,
isPlainObject,
toArray,
notNullorUndefined,
DataContainerInterface,
getSampleContainerData
Expand Down Expand Up @@ -355,8 +356,9 @@ class Layer {
*/
get defaultPointColumnPairs(): ColumnPairs {
return {
lat: {pair: 'lng', fieldPairKey: 'lat'},
lng: {pair: 'lat', fieldPairKey: 'lng'}
lat: {pair: ['lng', 'altitude'], fieldPairKey: 'lat'},
lng: {pair: ['lat', 'altitude'], fieldPairKey: 'lng'},
altitude: {pair: ['lng', 'lat'], fieldPairKey: 'altitude'}
};
}

Expand Down Expand Up @@ -546,11 +548,8 @@ class Layer {

/**
* Assign a field to layer column, return column config
* @param key - Column Key
* @param field - Selected field
* @returns {{}} - Column config
*/
assignColumn(key: string, field: Field): LayerColumns {
assignColumn(key: string, field: {name: string; fieldIdx: number}): LayerColumns {
// field value could be null for optional columns
const update = field
? {
Expand All @@ -570,30 +569,41 @@ class Layer {

/**
* Assign a field pair to column config, return column config
* @param key - Column Key
* @param pair - field Pair
* @returns Column config
*/
assignColumnPairs(key: string, pair: FieldPair): LayerColumns {
assignColumnPairs(key: string, fieldPairs: FieldPair): LayerColumns {
if (!this.columnPairs || !this.columnPairs?.[key]) {
// should not end in this state
return this.config.columns;
}
// key = 'lat'
const {pair, fieldPairKey} = this.columnPairs?.[key];

const {pair: partnerKey, fieldPairKey} = this.columnPairs?.[key] || {};

if (!pair[fieldPairKey]) {
if (typeof fieldPairKey === 'string' && !pair[fieldPairKey]) {
// do not allow `key: undefined` to creep into the `updatedColumn` object
return this.config.columns;
}

const {fieldPairKey: partnerFieldPairKey} = this.columnPairs?.[partnerKey] || {};

return {
// pair = ['lng', 'alt] | 'lng'
const updatedColumn = {
...this.config.columns,
[key]: pair[fieldPairKey],
[partnerKey]: pair[partnerFieldPairKey]
// @ts-expect-error fieldPairKey can be string[] here?
[key]: fieldPairs[fieldPairKey]
};

const partnerKeys = toArray(pair);
for (const partnerKey of partnerKeys) {
if (
this.config.columns[partnerKey] &&
this.columnPairs?.[partnerKey] &&
// @ts-ignore
fieldPairs[this.columnPairs?.[partnerKey].fieldPairKey]
) {
// @ts-ignore
updatedColumn[partnerKey] = fieldPairs[this.columnPairs?.[partnerKey].fieldPairKey];
}
}

return updatedColumn;
}

/**
Expand Down
96 changes: 96 additions & 0 deletions src/layers/src/geojson-layer/geojson-info-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import React from 'react';
import styled from 'styled-components';
import ReactMarkdown from 'react-markdown';
import {useIntl} from 'react-intl';

import {FormattedMessage} from '@kepler.gl/localization';

import Table from '../table';

const InfoModal = styled.div`
font-size: 13px;
color: ${props => props.theme.titleColorLT};
pre {
padding: 12px;
background-color: #f8f8f9;
}
`;

const StyledTitle = styled.div`
font-size: 20px;
letter-spacing: 1.25px;
margin: 18px 0 14px 0;
color: ${props => props.theme.titleColorLT};
`;

const StyledCode = styled.code`
color: ${props => props.theme.titleColorLT};
`;

const exampleTableHeader = ['id', 'latitude', 'longitude', 'sort by'];
const exampleTabbleRows = [
['A', '40.81773', '-74.20986', '0'],
['A', '40.81765', '-74.20987', '1'],
['A', '40.81746', '-74.20998', '2'],
['B', '40.64375', '-74.33242', '0'],
['B', '40.64353', '-74.20987', '1'],
['B', '40.64222', '-74.33001', '2']
];

const ExampleTable = () => (
<Table className="geojson-example-table">
<thead>
<tr>
{exampleTableHeader.map(v => (
<th key={v}>{v}</th>
))}
</tr>
</thead>
<tbody>
{exampleTabbleRows.map((row, i) => (
<tr key={i}>
{row.map((v, j) => (
<td key={j}>
<StyledCode>{v}</StyledCode>
</td>
))}
</tr>
))}
</tbody>
</Table>
);

const GeojsonInfoModalFactory = columnMode => {
const GeojsonInfoModal = () => {
const intl = useIntl();
return (
<InfoModal className="geojson-info-modal">
<div className="geojson-info-modal__description">
<ReactMarkdown
children={intl.formatMessage({
id:
columnMode === 'geojson'
? 'modal.polygonInfo.description'
: 'modal.polygonInfo.descriptionTable'
})}
/>
</div>
{columnMode === 'table' ? (
<div className="geojson-info-modal__example">
<StyledTitle>
<FormattedMessage id="modal.polygonInfo.exampleTable" />
</StyledTitle>
<ExampleTable />
</div>
) : null}
</InfoModal>
);
};
return GeojsonInfoModal;
};

export default GeojsonInfoModalFactory;
Loading

0 comments on commit b8b26a8

Please sign in to comment.