Skip to content
Docs version
@hungpvq/vue-map@1.1.0@hungpvq/vue-map-core@1.1.0@hungpvq/vue-map-dataset@1.1.0@hungpvq/vue-map-draw@1.1.0@hungpvq/map-draw@1.1.0@hungpvq/react-map@1.1.0@hungpvq/react-map-core@1.1.0@hungpvq/react-map-dataset@1.1.0@hungpvq/react-map-draw@1.1.0

Create Control

Dialog to add a GeoJSON / raster / vector dataset from the UI. LayerControl opens this when Create layer is clicked — you usually do not mount it yourself.

GeoJSON / KML / GPX / Shapefile file read, parse, and CRS reproject run in a Web Worker. Configure Vite worker.format: 'es' (and nxViteTsPaths on worker.plugins in this Nx workspace) or large files fall back to the main thread and can freeze the UI. Mount WorkerControl to watch progress and errors.

Optional GIS peers

@hungpvq/map-dataset does not bundle GIS format parsers. Install them in the app when using CreateControl / file import:

bash
npm i shpjs papaparse jszip topojson-client @tmcw/togeojson @xmldom/xmldom
FormatPeer(s)
GeoJSON / GeoJSONL / WKTnone (parseGisText sync)
CSVpapaparse
KML / GPX@tmcw/togeojson, @xmldom/xmldom
TopoJSONtopojson-client
ZIP / KMZjszip (+ KML peers for KMZ)
Shapefileshpjs

Programmatic parse: parseGisTextAsync / loadGis*Async from @hungpvq/map-dataset/create-control — see GIS worker.

UX notes

  • The dialog keeps a small draft in sessionStorage (type, name, CRS) via loadCreateControlDraft / saveCreateControlDraft.
  • If loaded file CRS differs from selected CRS, UI warns that data will be reprojected.
  • Multi-file upload accepts one GIS file, or one shapefile set (.shp + sidecars / .zip).
  • Folder drop: dropping a directory walks entries (collectFilesFromDataTransfer) and keeps GIS extensions only.
  • OS paste: on the File tab, paste clipboard files as upload, or paste text to switch to Raw and parse (readClipboardGisPaste / parseCreateControlPastedText).

Implementation (adapters)

Create / validate / defaults live on core LayerHelper from @hungpvq/map-dataset/create-control. Vue and React adapters only supply framework form UI (geojson upload, raster URL, settings) as leaf modules — there is no adapter helper/ wrapper or config/index barrel.

Import
ProtocolLayerHelper, LAYER_TYPES, parse/upload helpers from @hungpvq/map-dataset/create-control
Vue formsCreateControl/config/*.vue leaf SFCs
React formsCreateControl/config/CreateConfigForm.tsx (+ createControlComponentKey)

Props

PropDescriptionTypeRequiredDefault Value
mapIdstringfalse--
dragIdstringfalse--
btnWidthnumberfalse40
controlOrderCSS flex order for the standalone buttonnumberfalse0
position'top-left', 'top-right', 'bottom-left', 'bottom-right'false'bottom-right'
controlLayout'standalone' (corner), 'toolbar' (always in toolbar), 'button' (always corner; not auto-promoted on mobile)'standalone' | 'toolbar' | 'button'false'standalone'
controlVisiblebooleanfalsetrue

Map also accepts buttonInMobile ('button' | 'toolbar' | 'menu', default 'button'). On viewports ≤640px:

  • 'button' — leave corner buttons unchanged
  • 'toolbar' — move declared control buttons into a single ToolbarControl host (except controlLayout="button"). Mount one ToolbarControl in the map slot
  • 'menu' — hide per-control corner buttons; fan out intact clusters by position into corner stacks with outside-in More. Mount one ToolbarControl.

See ToolbarControl.

PropTypeRequiredEffect
showbooleanyesOpen the dialog

Events

NamePayloadFramework
update:showbooleanVue (v-model:show)
onShowChange(show: boolean) => voidReact

Vue

vue
<script setup lang="ts">
import { ref } from 'vue';
import { Map } from '@hungpvq/vue-map-core';
import { CreateControl } from '@hungpvq/vue-map-dataset';
import '@hungpvq/map-core/style.css';
import '@hungpvq/map-dataset/style.css';
import '@hungpvq/vue-map-core/style.css';
import '@hungpvq/vue-map-dataset/style.css';
import '@hungpvq/vue-draggable/style.css';

const open = ref(false);
</script>

<template>
  <Map>
    <CreateControl v-model:show="open" />
  </Map>
</template>

React

tsx
const [open, setOpen] = useState(false);
<CreateControl show={open} onShowChange={setOpen} />