refactor(B5): shared geometry module factory for mun/TI (F3)
Extract buildGeometryModuleFromTopology to collapse the duplicate topojson.feature → features → optional Map pipeline in municipality and territory geometry submodules. F2 (ensureCachedDownload) was already delivered in scripts/lib/cli.mjs via P3-H. Closes #28
This commit is contained in:
parent
e2bc366c10
commit
ce67738485
3 changed files with 99 additions and 19 deletions
85
src/lib/bahiaGeometryModuleFactory.ts
Normal file
85
src/lib/bahiaGeometryModuleFactory.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import { feature } from 'topojson-client'
|
||||
|
||||
import type { Feature, MultiPolygon, Polygon } from 'geojson'
|
||||
import type { GeometryCollection, Topology } from 'topojson-specification'
|
||||
|
||||
type PolygonalFeature<Properties extends Record<string, unknown>> = Feature<
|
||||
Polygon | MultiPolygon,
|
||||
Properties
|
||||
>
|
||||
|
||||
type GeometryModuleBase<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
> = {
|
||||
topology: Topology<{ [key in TObjectName]: GeometryCollection<Properties> }>
|
||||
features: readonly PolygonalFeature<Properties>[]
|
||||
}
|
||||
|
||||
type IndexedGeometryModule<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
KeyProperty extends keyof Properties & string,
|
||||
> = GeometryModuleBase<Properties, TObjectName> & {
|
||||
getFeatureByKey: (key: Properties[KeyProperty]) => PolygonalFeature<Properties> | undefined
|
||||
}
|
||||
|
||||
type BuildGeometryModuleOptions<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
KeyProperty extends keyof Properties & string,
|
||||
> = {
|
||||
topology: Topology<{ [key in TObjectName]: GeometryCollection<Properties> }>
|
||||
objectName: TObjectName
|
||||
keyProperty?: KeyProperty
|
||||
}
|
||||
|
||||
export function buildGeometryModuleFromTopology<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
KeyProperty extends keyof Properties & string,
|
||||
>(
|
||||
options: BuildGeometryModuleOptions<Properties, TObjectName, KeyProperty> & {
|
||||
keyProperty: KeyProperty
|
||||
},
|
||||
): IndexedGeometryModule<Properties, TObjectName, KeyProperty>
|
||||
|
||||
export function buildGeometryModuleFromTopology<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
>(
|
||||
options: BuildGeometryModuleOptions<Properties, TObjectName, never>,
|
||||
): GeometryModuleBase<Properties, TObjectName>
|
||||
|
||||
export function buildGeometryModuleFromTopology<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
KeyProperty extends keyof Properties & string,
|
||||
>({
|
||||
topology,
|
||||
objectName,
|
||||
keyProperty,
|
||||
}: BuildGeometryModuleOptions<Properties, TObjectName, KeyProperty>):
|
||||
| GeometryModuleBase<Properties, TObjectName>
|
||||
| IndexedGeometryModule<Properties, TObjectName, KeyProperty> {
|
||||
const features = feature(topology, topology.objects[objectName])
|
||||
.features as PolygonalFeature<Properties>[]
|
||||
|
||||
const base: GeometryModuleBase<Properties, TObjectName> = {
|
||||
topology,
|
||||
features,
|
||||
}
|
||||
|
||||
if (!keyProperty) {
|
||||
return base
|
||||
}
|
||||
|
||||
const featuresByKey = new Map(
|
||||
features.map((entry) => [entry.properties[keyProperty], entry]),
|
||||
)
|
||||
|
||||
return {
|
||||
...base,
|
||||
getFeatureByKey: (key) => featuresByKey.get(key),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,19 @@
|
|||
import { feature } from 'topojson-client'
|
||||
|
||||
import type {
|
||||
BahiaMunicipalityFeature,
|
||||
MunicipalityGeometryModule,
|
||||
MunicipalityTopology,
|
||||
} from '@/lib/bahiaGeometriesTypes'
|
||||
import { buildGeometryModuleFromTopology } from '@/lib/bahiaGeometryModuleFactory'
|
||||
import municipalityTopologyJson from '@/lib/geometries/bahia-municipalities.topo.json'
|
||||
|
||||
const topology = municipalityTopologyJson as unknown as MunicipalityTopology
|
||||
|
||||
const municipalityFeatures = feature(topology, topology.objects.municipalities)
|
||||
.features as BahiaMunicipalityFeature[]
|
||||
|
||||
const municipalityByCodarea = new Map(
|
||||
municipalityFeatures.map((entry) => [entry.properties.codarea, entry]),
|
||||
)
|
||||
const { topology, features, getFeatureByKey } = buildGeometryModuleFromTopology({
|
||||
topology: municipalityTopologyJson as unknown as MunicipalityTopology,
|
||||
objectName: 'municipalities',
|
||||
keyProperty: 'codarea',
|
||||
})
|
||||
|
||||
export const municipalityGeometryModule: MunicipalityGeometryModule = {
|
||||
topology,
|
||||
features: municipalityFeatures,
|
||||
getMunicipalityFeature: (codarea: string) => municipalityByCodarea.get(codarea),
|
||||
features: features as readonly BahiaMunicipalityFeature[],
|
||||
getMunicipalityFeature: getFeatureByKey,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
import { feature } from 'topojson-client'
|
||||
|
||||
import type {
|
||||
BahiaTerritoryFeature,
|
||||
TerritoryGeometryModule,
|
||||
TerritoryTopology,
|
||||
} from '@/lib/bahiaGeometriesTypes'
|
||||
import { buildGeometryModuleFromTopology } from '@/lib/bahiaGeometryModuleFactory'
|
||||
import territoryTopologyJson from '@/lib/geometries/bahia-identity-territories.topo.json'
|
||||
|
||||
const topology = territoryTopologyJson as unknown as TerritoryTopology
|
||||
|
||||
const territoryFeatures = feature(topology, topology.objects.territories)
|
||||
.features as BahiaTerritoryFeature[]
|
||||
const { topology, features } = buildGeometryModuleFromTopology({
|
||||
topology: territoryTopologyJson as unknown as TerritoryTopology,
|
||||
objectName: 'territories',
|
||||
})
|
||||
|
||||
export const territoryGeometryModule: TerritoryGeometryModule = {
|
||||
topology,
|
||||
features: territoryFeatures,
|
||||
features: features as readonly BahiaTerritoryFeature[],
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue