Að smíða viðbótareiningu
Hitakort, GeoJSON-lagið og þyrping merkja eru öll sérstakir pakkar sem hnýttir eru utan á, án þess að Core sé breytt. Sama viðmót er opið öllum, svo þriðji aðili getur gefið út sína eigin viðbót á sama hátt. Þessi síða lýsir því hvernig.
00 · Hvað viðbót er
Viðbótareining er sjálfstæður pakki sem reiðir sig aðeins á kjarnaeininguna — aldrei á pakka þjónustuaðila (react-for-*, android-for-*, ios-for-*). Haltu þeirri línu og viðbótin þín virkar hvaða kortaþjónustuaðila sem notandinn valdi.
Notaðu aðeins opinberu gerðir kjarnans — stöður, safnara, samninga stýringa, flísaþjóninn, þjónustuskrána.
Að flytja inn pakka þjónustuaðila. Að varpa stýringunni í aðra gerð til að ná í innra svið.
Viðbæturnar þrjár sem þegar eru gefnar út eru fyrirmyndarútfærslurnar. Stysta leiðin er að lesa þá sem er næst því sem þú vilt smíða.
heatmap draws raster tiles itself · tile server + RasterLayer geojson-layer turns bulk vectors into tiles · tile server + RasterLayer marker-clustering reworks markers and hands back · MarkerState + service registry
01 · Búðu til pakkann
Reiddu þig á kjarnann einan. Þjónustuaðilinn er valinn af forritinu sem notar pakkann, svo pakkinn þinn sér hann aldrei.
dependencies {
implementation("com.mapconductor:core")
implementation("com.mapconductor:compose") // Ef þú birtir Composable
// Ekki reiða þig á android-for-*
}.package(url: "https://github.com/MapConductor/ios-sdk-core", from: "1.3.1"),
.target(
name: "MyMapExtension",
dependencies: [.product(name: "MapConductorCore", package: "ios-sdk-core")]
// Ekki reiða þig á ios-for-*
){
"dependencies": {
"@mapconductor/js-sdk-core": "^0.1.1",
"@mapconductor/js-sdk-react": "^0.1.1"
},
"peerDependencies": { "react": "^18.0.0 || ^19.0.0" }
}02 · Skilgreindu stöðuna þína
Notendur þínir halda á stöðuhlut. Fylgdu sama formi og stöðugerðir kjarnans (MarkerState og félagar) og þeir þurfa ekkert nýtt að læra. Gefðu honum fingrafar svo hann komist á safnara kjarnans og þú færð mismunauppfærslur án fyrirhafnar.
OverlayCollector an id → state map; gathers add/remove/diff and change notifications ComponentState the contract for a state that carries an id (Android) fingerPrint() a comparison value holding only what affects drawing
03 · Veldu teikniútgang
Þetta er hönnunarákvörðunin sem skiptir máli. Ekki skrifa teiknikóða fyrir hvern þjónustuaðila — matað útgang sem kjarninn hefur þegar. Þeir eru tveir.
Teiknaðu þínar eigin flísar
Skráðu teiknifall hjá staðbundna flísaþjóninum og settu eitt RasterLayer sem vísar á vefslóðarsniðmát hans. Hitakortið og GeoJSON-lagið vinna bæði svona. Það skalast með gagnamagni og lítur nákvæmlega eins út hjá hverjum þjónustuaðila.
Skilaðu merkjum eða formum
Umbreyttu inntakinu þínu í MarkerState / PolygonState og skrifaðu það í safnarann; venjuleg leið þjónustuaðilans tekur við þaðan. Þyrping vinnur svona, og smellir og drættir halda áfram að virka.
val tileServer = TileServerRegistry.get()
val renderer = MyTileRenderer(tileSize = 256) // Geymir fallið sem teiknar eina flís
DisposableEffect(groupId) {
tileServer.register(groupId, renderer)
onDispose { tileServer.unregister(groupId) }
}
val layer = remember {
RasterLayerState(
id = "my-ext-$groupId",
source = RasterLayerSource.UrlTemplate(
template = tileServer.urlTemplate(groupId, renderer.tileSize),
tileSize = renderer.tileSize,
scheme = TileScheme.XYZ,
),
)
}
RasterLayer(layer)public struct MyOverlay: MapOverlayItemProtocol, View {
let state: MyOverlayState
public func append(to content: inout MapViewContent) {
// Tengt inn nákvæmlega eins og HeatmapOverlay í ios-heatmap
content.rasterLayers.append(RasterLayer(state: state.rasterLayerState))
}
}import { createRasterLayerState, TileServerRegistry, TileScheme } from '@mapconductor/js-sdk-core';
import { RasterLayer } from '@mapconductor/js-sdk-react';
const tileServer = TileServerRegistry.get();
useEffect(() => {
tileServer.register(groupId, renderer); // Teiknarinn teiknar eina flís
return () => { tileServer.unregister(groupId); };
}, [groupId, tileServer, renderer]);
const state = useRef(createRasterLayerState({
id: `my-ext-${groupId}`,
source: {
kind: 'urlTemplate',
template: tileServer.urlTemplate(groupId, renderer.tileSize),
tileSize: renderer.tileSize,
scheme: TileScheme.XYZ,
},
})).current;
return <RasterLayer state={state} />;04 · Myndavél og frágangur
Ef þú vilt fylgja aðdrætti og hliðrun máttu ekki snerta hlustendur kortastýringarinnar sjálfrar: þeir eru einnar raufar og tvær viðbætur munu bítast um þá í forriti notandans. Skráðu þig sem yfirlagsstýringu og myndavélarbreytingar berast eftir sömu leið og til allra annarra yfirlaga.
class MyCameraController(
private val renderer: MyTileRenderer,
) : OverlayControllerInterface<Unit, Unit>, OnCameraChangeReceiverInterface {
override val zIndex: Int = 0
override suspend fun add(data: List<Unit>) {}
override suspend fun update(state: Unit) {}
override suspend fun clear() {}
override fun find(position: GeoPointInterface): Unit? = null
override suspend fun onCameraChanged(mapCameraPosition: MapCameraPosition) {
renderer.updateCameraZoom(mapCameraPosition.zoom)
}
override fun destroy() {}
}
// Skrá það
val mapController = LocalMapViewController.current
DisposableEffect(mapController, cameraController) {
mapController.registerOverlayController(cameraController)
onDispose { cameraController.destroy() }
}public final class MyCameraController: OverlayControllerProtocol {
public typealias StateType = Void
public typealias EntityType = Void
public typealias EventType = Void
public let zIndex: Int = 0
public var clickListener: ((Void) -> Void)?
public func add(data: [Void]) async {}
public func update(state: Void) async {}
public func clear() async {}
public func find(position: GeoPointProtocol) -> Void? { nil }
public func onCameraChanged(mapCameraPosition: MapCameraPosition) async {
renderer.updateCameraZoom(mapCameraPosition.zoom)
}
public func destroy() {}
}public func append(to content: inout MapViewContent) {
// Á iOS er kortainnihaldið gildi af gerðinni MapViewContent en ekki sýnastigveldi, svo
// stýringin er nálguð gegnum MapServiceRegistryScope
MapServiceRegistryScope.current
.get(OverlayControllerRegistryKey.self)?
.register(cameraController)
content.rasterLayers.append(RasterLayer(state: rasterLayerState))
}// Rétta leiðin til að lesa myndavélina er staðan; sýnilega svæðið kemur líka þaðan:
// const camera = mapViewState.cameraPosition;
// const bounds = camera.visibleRegion?.bounds;
// Til að fylgjast með breytingum notaðu onCameraMove / onCameraMoveEnd, eða eins og að neðan
// skráðu yfirlagsstýringu og taktu við onCameraChanged.
export class MyCameraController implements OverlayController<void, void, void> {
readonly zIndex = 0;
clickListener: ((event: void) => void) | null = null;
constructor(private readonly renderer: MyTileRenderer) {}
add(): Promise<void> { return Promise.resolve(); }
update(): Promise<void> { return Promise.resolve(); }
clear(): Promise<void> { return Promise.resolve(); }
find(): void | null { return null; }
onCameraChanged(camera: MapCameraPosition): void {
this.renderer.updateCameraZoom(camera.zoom);
}
destroy(): void {}
}
// Skrá það
const { controller } = useContext(MapContext) ?? {};
useEffect(() => {
if (!controller) return;
controller.registerOverlayController?.(cameraController);
return () => { controller.unregisterOverlayController?.(cameraController); };
}, [controller, cameraController]);05 · Afhentu eiginleika
Aðeins nauðsynlegt þegar skrefin fjögur að ofan duga ekki: þegar þú þarft eitthvað sem aðeins þjónustuaðilinn getur smíðað, taktu það gegnum MapServiceRegistry. Skráning og uppfletting eru bundnar við gerðarbundinn lykil, svo engu er varpað.
Þyrping merkja er lifandi dæmið: innbyggðar merkjagerðir eru ólíkar milli þjónustuaðila, svo þyrpingin getur ekki smíðað teiknara sjálf. Hún sækir MarkerRenderingSupport sem þjónustuaðilinn skráði og lætur hann smíða teiknarann.
// Skilgreindu lykilinn sem singleton object object MyCapabilityKey : MapServiceKey<MyCapability> // Sæktu hann. Óskráður þýðir null, svo ákveddu hvort haldið er áfram án eiginleikans eða hætt val services = LocalMapServiceRegistry.current val capability = services.get(MyCapabilityKey) ?: return
// Ein skrá á hvert kort, geymd af stöðunni (eins og í react og ios)
state.serviceRegistry.put(MyCapabilityKey, myCapability)
// Þegar það hverfur notaðu remove(), ekki clear(), svo aðrir eiginleikar fari ekki með
DisposableEffect(state) {
onDispose { state.serviceRegistry.remove(MyCapabilityKey) }
}// Skilgreindu lykilinn sem gerð sem uppfyllir MapServiceKey
public enum MyCapabilityKey: MapServiceKey {
public typealias Value = any MyCapability
}
// Skráin sést aðeins á meðan verið er að setja saman content
guard let capability = MapServiceRegistryScope.current.get(MyCapabilityKey.self) else { return }import { createMapServiceKey } from '@mapconductor/js-sdk-core';
import { useMapServiceRegistry } from '@mapconductor/js-sdk-react';
export const MyCapabilityKey = createMapServiceKey<MyCapability>();
const services = useMapServiceRegistry();
const capability = services.get(MyCapabilityKey);
if (!capability) return null; // Slökktu hljóðlega á því hjá þjónustuaðilum þar sem það er óskráð// Ein skrá á hvert kort, geymd af stöðunni state.serviceRegistry.put(MyCapabilityKey, myCapability); // Við aftengingu notaðu remove(), ekki clear(), svo aðrir eiginleikar fari ekki með state.serviceRegistry.remove(MyCapabilityKey);
Reglur sem gilda
Haltu þessum fjórum og viðbótin þín lifir af skipti um þjónustuaðila og þolir aðrar viðbætur við hlið sér.
1 · Flyttu aldrei inn pakka þjónustuaðila
Ef þér finnst þú þurfa þess, þá er það eiginleiki sem þú ættir að taka gegnum þjónustuskrána.
2 · Varpaðu aldrei stýringunni til að ná í innviði
react-heatmap gerði einmitt þetta áður og geymdi og endurheimti einnar-raufar myndavélarhlustandann. Tvær viðbætur myndu skrifa hvor yfir aðra. Nú notar hún opinbera registerOverlayController í staðinn.
3 · Afskráðu allt sem þú skráir
Yfirlagsstýringar, hópar á flísaþjóninum, lyklar í skránni. remove() tekur til baka nákvæmlega eina færslu.
4 · Dofnaðu hljóðlega þegar ekkert finnst
Hjá þjónustuaðila sem skráir ekki það sem þú þarft, teiknaðu ekkert frekar en að kasta villu. Restin af skjá notandans heldur áfram að virka.