Back to Home

Geoorganizer: data model and synchronization

Personal Geoorganizer uses a model with atomic Points, Places, Routes, and hierarchical Folders. Synchronization via dirty tracking and batch requests ensures reactivity. Suitable for middle/senior developers, stack: PHP, Vue 3, MariaDB.

Build a Geoorganizer: from model to synchronization
Advertisement 728x90

Architecture of a Personal Geodata Organizer: Model and Synchronization

A personal geodata organizer addresses the challenge of structuring personal spatial data through a clear entity model. Key components include: Point as atomic geometry, Place with metadata, Route as a sequence of points, and Folder for hierarchy. This structure enables building object trees without duplicating coordinates, ensuring interface reactivity.

Points store only latitude, longitude, altitude, and a UUIDv4. They are independent of other entities and serve as reference elements. Each Place references a single Point by ID, adding a name, description, photo albums, and links. Routes contain an ordered list of point IDs, supporting repetitions for non-linear scenarios. Folders organize Places and Routes into trees with parent, context, and srt fields for sorting.

Entities in Detail

Point

Pure geometry without context. Stored as binary(16) in MariaDB/MySQL for index optimization. References to it are UUIDv4 strings on the frontend.

Google AdInline article slot

Place

Metadata attached to a Point. Example: A Point ID with a description like "Gazebo for the first meeting" and a photo album. Position in the tree is determined by folderid.

Route

Sequence of Point IDs with meta-descriptions. A single Point can repeat, suitable for loops or returns. Example: route "Evening walk" — home → store → park (multiple points) → library → home.

Folder

Tree structure with fields id, parent, srt (fractional for order), context (places or routes). The tree is built reactively from a flat list.

Google AdInline article slot

Tech Stack and Database

Backend in PHP, frontend — Vue 3 with Composition API, TypeScript, Pinia, and Axios. Database — MariaDB/MySQL. Entities in tables points, places, routes, folders.

Key feature — atomicity of Points: they are unaware of consumers, minimizing duplication and simplifying updates.

Synchronizing Changes

The client tracks dirty states of objects with flags added, updated, deleted in the Pinia store. Example object:

Google AdInline article slot
{
	"id": "e7c6c8c4-4e3b-4d2f-8b61-8c9eaa2c1d51",
	"title": "Gazebo",
	"pointid": "a2c17b8f...",
	"added": false,
	"updated": true,
	"deleted": false
}

Filtering before sending: only changed objects, excluding added+deleted in the same session.

Batch Sending to Server

The "Save" button forms a single request with a batch:

{
	"userid": "...",
	"sessionid": "...",
	"data": {
		"points": [...],
		"places": [...],
		"routes": [...],
		"folders": [...]
	}
}

The server applies operations in order: DELETE > INSERT > UPDATE, as a mini-transaction.

Advantages of this approach:

  • Minimal number of requests — one batch per series of edits.
  • Reactive UI: working with a local data copy.
  • Server simplicity: one endpoint without multiple routes.
  • Scalability: new entities added to the batch without protocol changes.

Key Takeaways

  • Atomic Points ensure referential integrity without duplicating geodata.
  • Tree model via Folders is built reactively on the frontend.
  • Dirty tracking + batch synchronization reduce network load.
  • Stack (PHP/Vue 3/Pinia/MariaDB) balances simplicity and performance.
  • Open-source project on GitHub with demo under test/test.

— Editorial Team

Advertisement 728x90

Read Next