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

Rewrite null values in SHP export to prevent them from being dropped #556

Merged
merged 1 commit into from Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added Shapefile export [#516](https://github.com/PublicMapping/districtbuilder/pull/516)
- Added Shapefile export [#516](https://github.com/PublicMapping/districtbuilder/pull/516) & [#556](https://github.com/PublicMapping/districtbuilder/pull/556)
- Allow copying maps [#526](https://github.com/PublicMapping/districtbuilder/pull/526)
- Reduce problem with hidden base geounits [#528](https://github.com/PublicMapping/districtbuilder/pull/528)
- Find non-contiguous [#531](https://github.com/PublicMapping/districtbuilder/pull/531)
Expand Down
36 changes: 18 additions & 18 deletions src/client/components/ProjectSidebar.tsx
Expand Up @@ -3,8 +3,8 @@ import React, { memo, useEffect, useState, Fragment } from "react";
import { Box, Button, Flex, jsx, Styled, ThemeUIStyleObject } from "theme-ui";

import {
CompactnessScore,
DemographicCounts,
DistrictProperties,
GeoUnitHierarchy,
GeoUnits,
IProject,
Expand Down Expand Up @@ -208,8 +208,8 @@ const ProjectSidebar = ({

const BLANK_VALUE = "–";

function getCompactnessDisplay(compactness: CompactnessScore) {
return compactness === null ? (
function getCompactnessDisplay(properties: DistrictProperties) {
return properties.contiguity === "" ? (
<Tooltip
placement="top-start"
content={
Expand All @@ -220,19 +220,7 @@ function getCompactnessDisplay(compactness: CompactnessScore) {
>
<span sx={{ color: "gray.2" }}>{BLANK_VALUE}</span>
</Tooltip>
) : typeof compactness === "number" ? (
<Tooltip
placement="top-start"
content={
<span>
<strong>{Math.floor(compactness * 100)}% compactness.</strong> Calculated using the
Polsby-Popper measurement
</span>
}
>
<span>{`${Math.floor(compactness * 100)}%`}</span>
</Tooltip>
) : compactness === "non-contiguous" ? (
) : properties.contiguity === "non-contiguous" ? (
<Tooltip
placement="top-start"
content={
Expand All @@ -246,8 +234,20 @@ function getCompactnessDisplay(compactness: CompactnessScore) {
<Icon name="alert-triangle" color="#f06543" size={0.95} />
</span>
</Tooltip>
) : properties.contiguity === "contiguous" ? (
<Tooltip
placement="top-start"
content={
<span>
<strong>{Math.floor(properties.compactness * 100)}% compactness.</strong> Calculated using
the Polsby-Popper measurement
</span>
}
>
<span>{`${Math.floor(properties.compactness * 100)}%`}</span>
</Tooltip>
) : (
assertNever(compactness)
assertNever(properties.contiguity)
);
}

Expand Down Expand Up @@ -291,7 +291,7 @@ const SidebarRow = memo(
districtId === 0 ? (
<span sx={style.blankValue}>{BLANK_VALUE}</span>
) : (
getCompactnessDisplay(district.properties.compactness)
getCompactnessDisplay(district.properties)
);
const toggleHover = () => setHover(!isHovered);
const toggleLocked = (e: React.MouseEvent) => {
Expand Down
29 changes: 17 additions & 12 deletions src/server/src/districts/entities/geo-unit-topology.entity.ts
Expand Up @@ -14,7 +14,7 @@ import polygonToLine from "@turf/polygon-to-line";

import {
UintArrays,
CompactnessScore,
Contiguity,
GeoUnitCollection,
GeoUnitDefinition,
HierarchyDefinition,
Expand All @@ -33,26 +33,26 @@ interface GeoUnitHierarchy {
*
* See https://fisherzachary.github.io/public/r-output.html#polsby-popper
*/
function calcPolsbyPopper(feature: Feature): CompactnessScore {
function calcPolsbyPopper(feature: Feature): [number, Contiguity] {
if (
feature.geometry &&
feature.geometry.type === "MultiPolygon" &&
feature.geometry.coordinates.length === 0
) {
return null;
return [0, ""];
}
if (
feature.geometry &&
feature.geometry.type === "MultiPolygon" &&
feature.geometry.coordinates.length > 1
) {
return "non-contiguous";
return [0, "non-contiguous"];
}
const districtArea: number = area(feature);
// @ts-ignore
const outline = polygonToLine(feature);
const districtPerimeter: number = length(outline, { units: "meters" });
return (4 * Math.PI * districtArea) / districtPerimeter ** 2;
return [(4 * Math.PI * districtArea) / districtPerimeter ** 2, "contiguous"];
}

// Creates a list of trees for the nested geometries of the geounits
Expand Down Expand Up @@ -247,13 +247,18 @@ export class GeoUnitTopology {
});
return {
...featureCollection,
features: featureCollection.features.map(feature => ({
...feature,
properties: {
...feature.properties,
compactness: calcPolsbyPopper(feature)
}
}))
features: featureCollection.features.map(feature => {
const [compactness, contiguity] = calcPolsbyPopper(feature);

return {
...feature,
properties: {
...feature.properties,
compactness,
contiguity
}
};
})
};
}

Expand Down
1 change: 1 addition & 0 deletions src/server/src/projects/controllers/projects.controller.ts
Expand Up @@ -26,6 +26,7 @@ import stringify from "csv-stringify/lib/sync";
import { Response } from "express";
import { FeatureCollection } from "geojson";
import { convert } from "geojson2shp";
import * as _ from "lodash";
import { GeometryCollection } from "topojson-specification";

import { MakeDistrictsErrors } from "../../../../shared/constants";
Expand Down
9 changes: 7 additions & 2 deletions src/shared/entities.d.ts
Expand Up @@ -34,7 +34,12 @@ export interface IDistrictsDefinition {
readonly districts: DistrictsDefinition;
}

export type DistrictProperties = { readonly [name: string]: number };
export type DistrictProperties = {
readonly contiguity: "contiguous" | "non-contiguous" | "";
readonly compactness: number;
} & {
readonly [name: string]: number;
};

export interface IStaticFile {
readonly id: string;
Expand Down Expand Up @@ -154,7 +159,7 @@ export interface MutableGeoUnits {
[geoLevelId: string]: Map<FeatureId, GeoUnitIndices>;
}

export type CompactnessScore = number | null | "non-contiguous";
export type Contiguity = "" | "contiguous" | "non-contiguous";

export type DistrictId = number;

Expand Down