Merge pull request #75 from fsolla/cursor/b5-geometry-factory-ac3f
B5 — Cache CLI compartilhado + factory mun/TI (F2–F3)
This commit is contained in:
commit
99330f845d
5 changed files with 102 additions and 22 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Escala e DRY pós-B2 (geometrias + scripts CLI)
|
||||
|
||||
Status: Fase 1 entregue com B3 (2026-07-19); Fases 2–3 pendentes
|
||||
Atualizado em: 2026-07-27 (`capture-review-debts` pós-B8+: `scripts/lib/topology.mjs` resolve por precedente onde o helper da F2 vive — `scripts/lib/`, não `src/lib/`; 2026-07-26 pós-B8 F2: 5º call site; 2026-07-20 pós-A8: `build-bahia-demographics.mjs` reforça o gatilho da F2 como 4º call site)
|
||||
Status: Fases 1–3 entregues (F1 com B3 em 2026-07-19; F2 em P3-H/`scripts/lib/cli.mjs`; F3 em #28)
|
||||
Atualizado em: 2026-07-31 (F3: `bahiaGeometryModuleFactory.ts` + wrappers mun/TI)
|
||||
Item do roadmap: [docs/roadmap.md](../roadmap.md) (Trilha B, item B5)
|
||||
Responsável: —
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ import type { Feature, MultiPolygon, Polygon } from 'geojson'
|
|||
import type { GeometryCollection, Topology } from 'topojson-specification'
|
||||
|
||||
/** Every committed mesh is polygonal; only the properties differ. */
|
||||
type BahiaFeature<Properties> = Feature<Polygon | MultiPolygon, Properties>
|
||||
export type BahiaFeature<Properties extends Record<string, unknown>> = Feature<
|
||||
Polygon | MultiPolygon,
|
||||
Properties
|
||||
>
|
||||
|
||||
type BahiaMunicipalityProperties = {
|
||||
codarea: string
|
||||
|
|
|
|||
75
src/lib/bahiaGeometryModuleFactory.ts
Normal file
75
src/lib/bahiaGeometryModuleFactory.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { feature } from 'topojson-client'
|
||||
|
||||
import type { BahiaFeature } from '@/lib/bahiaGeometriesTypes'
|
||||
import type { GeometryCollection, Topology } from 'topojson-specification'
|
||||
|
||||
type GeometryModuleBase<Properties extends Record<string, unknown>, TObjectName extends string> = {
|
||||
topology: Topology<{ [key in TObjectName]: GeometryCollection<Properties> }>
|
||||
features: readonly BahiaFeature<Properties>[]
|
||||
}
|
||||
|
||||
type IndexedGeometryModule<
|
||||
Properties extends Record<string, unknown>,
|
||||
TObjectName extends string,
|
||||
KeyProperty extends keyof Properties & string,
|
||||
> = GeometryModuleBase<Properties, TObjectName> & {
|
||||
getFeatureByKey: (key: Properties[KeyProperty]) => BahiaFeature<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 BahiaFeature<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,23 @@
|
|||
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<
|
||||
BahiaMunicipalityFeature['properties'],
|
||||
'municipalities',
|
||||
'codarea'
|
||||
>({
|
||||
topology: municipalityTopologyJson as unknown as MunicipalityTopology,
|
||||
objectName: 'municipalities',
|
||||
keyProperty: 'codarea',
|
||||
})
|
||||
|
||||
export const municipalityGeometryModule: MunicipalityGeometryModule = {
|
||||
topology,
|
||||
features: municipalityFeatures,
|
||||
getMunicipalityFeature: (codarea: string) => municipalityByCodarea.get(codarea),
|
||||
features,
|
||||
getMunicipalityFeature: getFeatureByKey,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
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<
|
||||
BahiaTerritoryFeature['properties'],
|
||||
'territories'
|
||||
>({
|
||||
topology: territoryTopologyJson as unknown as TerritoryTopology,
|
||||
objectName: 'territories',
|
||||
})
|
||||
|
||||
export const territoryGeometryModule: TerritoryGeometryModule = {
|
||||
topology,
|
||||
features: territoryFeatures,
|
||||
features,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue