A Simple Image Map Editor, Easily create, edit, import, export your GeoJSON for Images with Leaflet! All with a intuitive UX, built on top of Leaflet and Geoman
- Custom Images: Simple upload of images to use as maps
- Beautiful UI: Natural and Intuitive UI for editing and creating map features, thanks to Daisy UI
- Mobile Friendly: Fully supports mobile devices from editing to exporting
- Local Saving: Working on a large project? Save your work locally and easily load it back in later
- GeoJSON Import/Export: Easily import and export your GeoJSON for your Images
- Options: Easily customize your map with options like zoom, center, and even dimensions
- Infinite Possibilities: You can create your own map with any number of features, and any number of properties
Add an image to your map by clicking the "Manage Image" button under the Image button in the top right corner of the UI.
You can either upload an image from your computer or use a hosted image from the internet.
You can add features to the current map by using the Geoman controls on the left side of the map
You can edit any feature using the editing tools in the second section of the Geoman controls.
Hint: You can edit, move, cut, remove and rotate map feature using the tools (Deletion can only be performed here).
PS: You can also edit the properties of a feature using the Properties panel.
You can edit the properties of a feature by using the list of features on the right.
Some properties override UI elements, like name and id. Try them out!
Be sure to save!
PS: If you need to persist the feature state see Persistance.
You can edit the maps options by clicking the manage map icon in the top right.
You can manage the maps, initialZoom, maxZoom, minZoom, height, width and center properties here.
Exporting and Downloading a generated list of features as GeoJSON is support by clicking on the export icon in the top right of the UI.
Importing geoJSON by uploading a file is supported though clicking the import icon in the top right of the UI.
Jelly supports persistance of your session so that you don't lose your progress on large jobs, however you must explicitly click the alerts to save the state locally.
If at any point you want to purge the local state you can click on the alerts in their success mode
The basic recipe for adding the exported geoJSON to you own map is the following: (written in typescript)
import type { Map } from "leaflet";
import {
Circle,
CRS,
geoJSON,
imageOverlay,
LatLngBounds,
map,
Marker,
} from "leaflet";
import geoJson from "./geojson.json"; // your geoJSON
let mapRef: Map | null = null;
const mapElement = document.getElementById("map")!;
const h = 100,
w = 100; // You need to know your images size
const url = ""; // Your image url
// Create the map
mapRef = map(mapElement, {
crs: CRS.Simple,
minZoom: -1,
maxZoom: 3,
zoom: -1,
center: [h, w],
});
// Add the image to the map
const southWest = mapRef.unproject([0, h], 0);
const northEast = mapRef.unproject([w, 0], 0);
const bounds = new LatLngBounds(southWest, northEast);
imageOverlay(url, bounds).addTo(mapRef);
mapRef.setMaxBounds(bounds);
// Add your geoJSON here
if (geoJson) {
geoJSON(geoJson, {
pointToLayer: (feature, latlng) => {
if (feature.properties.radius) {
return new Circle(latlng, feature.properties.radius);
} else {
return new Marker(latlng);
}
},
}).addTo(mapRef);
}
Contributors are welcome!
If you find an issue or have a feature request, please open an issue or pull request~. I will do my best to address them as soon as possible.
The project is a simple react vite project. With the preferred package manager of yarn. Get started with.
git clone https://github.com/yoroshikun/jelly-image-map-editor.git
cd jelly-image-map-editor
yarn
Please follow conventional-commits for the best practices of writing commits.
If you have troubles importing the geoJSON you may need to add a converter for circles and markers. (code below is in typescript)
import { geoJSON, Circle, Marker } from 'leaflet';
const addGeoJSON = (map: Map, geoJson: GeoJsonObject) => {
const geoJSONLayer = geoJSON(geoJson, {
pointToLayer: (feature, latlng) => {
if (feature.properties.radius) {
return new Circle(latlng, feature.properties.radius);
} else {
return new Marker(latlng);
}
},
}).addTo(map);