{"id":343743,"date":"2026-07-26T08:05:17","date_gmt":"2026-07-26T08:05:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/axismundi-geodata\/"},"modified":"2026-07-26T08:04:43","modified_gmt":"2026-07-26T08:04:43","slug":"axismundi-geodata","status":"publish","type":"plugin","link":"https:\/\/ky.wordpress.org\/plugins\/axismundi-geodata\/","author":21128503,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.2.3","stable_tag":"0.2.3","tested":"7.0.3","requires":"6.7","requires_php":"8.1","requires_plugins":null,"header_name":"Axismundi Geodata","header_author":"KIM JIWOON","header_description":"Canonical geo store for Axismundi \u2014 geo_area \/ geotag taxonomies and privacy-aware coordinate metadata for posts and attachments, exposed over REST for the editor, map blocks, and federation serializers.","assets_banners_color":"","last_updated":"2026-07-26 08:04:43","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Jiwoon-Kim\/axismundi\/tree\/main\/products\/distributables\/plugins\/axismundi-geodata","header_author_uri":"https:\/\/designbusan.ai.kr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":69,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"0.2.3":{"tag":"0.2.3","author":"kimjiwoon","date":"2026-07-26 08:04:43"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.2.3"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[2591,6341,2215,23853,91],"plugin_category":[49,57],"plugin_contributors":[270183],"plugin_business_model":[],"class_list":["post-343743","plugin","type-plugin","status-publish","hentry","plugin_tags-geo","plugin_tags-geotag","plugin_tags-location","plugin_tags-rest-api","plugin_tags-taxonomy","plugin_category-maps-and-location","plugin_category-taxonomy","plugin_contributors-kimjiwoon","plugin_committers-kimjiwoon"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/axismundi-geodata.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Axismundi Geodata is the data layer that lets posts and attachments carry a\nlocation, and lets the editor, map blocks, and federation serializers read it\nback through one shared model. It registers:<\/p>\n\n<ul>\n<li><strong><code>axismundi_geo_area<\/code><\/strong> \u2014 a hierarchical taxonomy for address \/ administrative\ncontainment (\ub300\ud55c\ubbfc\uad6d &gt; \ubd80\uc0b0\uad11\uc5ed\uc2dc &gt; \uc218\uc601\uad6c &gt; \uad11\uc548\ub3d9). Answers \"where is it?\".<\/li>\n<li><strong><code>axismundi_geotag<\/code><\/strong> \u2014 a flat taxonomy for place \/ content geo tags (\uad11\uc548\ub9ac\ud574\uc218\uc695\uc7a5,\n\uad11\uc548\ub300\uad50). Answers \"what place is it about?\".<\/li>\n<li><strong>Coordinate meta<\/strong> on posts, pages, and attachments \u2014 the observation \/\ncapture point, using the WordPress-convention <code>geo_latitude<\/code>, <code>geo_longitude<\/code>,\n  geo_public keys plus <code>ax_geo_*<\/code> extensions.<\/li>\n<li><strong>Place-fact term meta<\/strong> \u2014 centroid, display bounds \/ zoom, and external place id on\neach geo taxonomy term.<\/li>\n<\/ul>\n\n<p>The taxonomy identifiers are plugin-prefixed to avoid conflicts with other\nplugins. Their public permalink bases remain <code>\/geo-area\/<\/code> and <code>\/geotag\/<\/code>.<\/p>\n\n<p>Privacy is built into the model. The raw exact coordinate is stored, while\n    geo_public decides whether an attachment coordinate may leave the site.\nCallers ask the plugin for the public coordinate rather than reading raw meta.<\/p>\n\n<p>Attachments get a <strong>Location (GPS)<\/strong> editor on the Edit Media screen: latitude,\nlongitude, altitude, and a public toggle, plus an on-demand <strong>Import from EXIF<\/strong>\nbutton that reads the original file's GPS, and a Leaflet mini map with a draggable\nmarker (configure a tile provider under Settings \u2192 Geodata). Nothing is\nauto-imported or auto-published \u2014 the public toggle defaults off.<\/p>\n\n<p>Posts and pages express location through the Geo Area \/ Geotag taxonomies. The\nseparate Axismundi Map plugin consumes this data for front-end place, media,\ntrack, and geo-archive maps. Attachments carry coordinate meta only \u2014 they are\nnever auto-tagged with place terms. A future ax_note post type can opt into the\ngeo taxonomies through the <code>axismundi_geodata_object_types<\/code> filter.<\/p>\n\n<p>Both public taxonomies include plugin-owned block templates for their archive\npages. They retain the tonal archive header, current-term map, inherited card\nfeed, and geo navigation sidebar previously supplied by the Axismundi theme.\nThemes and site owners can still override them through the normal template\nhierarchy. The map remains optional; without Axismundi Map the archive feed and\nnavigation continue to render.<\/p>\n\n<p>The theme does not hard-code Geo taxonomy blocks. Insert the plugin-provided\n<strong>Post geo terms<\/strong> pattern where a post template should expose its areas and\nplaces.<\/p>\n\n<p>A demo place hierarchy (\ub300\ud55c\ubbfc\uad6d &gt; \ubd80\uc0b0\uad11\uc5ed\uc2dc &gt; \uc218\uc601\uad6c &gt; \uad11\uc548\ub3d9, with the\n\uad11\uc548\ub9ac\ud574\uc218\uc695\uc7a5 geotag) ships with the plugin but is created only on request \u2014 it\nis never seeded automatically. Run <code>wp axismundi-geodata seed-demo<\/code> to add it and\n    wp axismundi-geodata seed-demo --remove to drop it.<\/p>\n\n<p>Term editors can optionally look up a place from an external provider and bind it.\nProviders are configured under Settings \u2192 Geodata and are off by default: Google\nPlaces needs a server-side API key, and OpenStreetMap (Nominatim) is enabled by\nchoosing the public service (low-volume admin lookup only) or a custom endpoint.\nKeys and endpoints are used only from admin AJAX and are never sent to the\nbrowser. Selecting a candidate binds the term to a namespaced id \u2014\n    google: or <code>osm:node\/&lt;id&gt;<\/code> \/ <code>osm:way\/&lt;id&gt;<\/code> \u2014 and stores the returned\ncoordinates, address, and place type.<\/p>\n\n<p>For self-hosted maps, upload a <code>.pmtiles<\/code> map pack under Media. The plugin reads\nits tile format, schema, bounds, zoom, and attribution into editable attachment\nfields, and a Protomaps map pack can be chosen as the admin preview basemap under\nSettings \u2192 Geodata. Front-end provider settings are enabled when Axismundi Map is\nactive. The plugin never bundles or generates tile data.<\/p>\n\n<p>GPX and KML uploads are recognised as GPS tracks and exposed as GeoJSON through\nthe REST API. Geotags and public GPS media are also available as GeoJSON for map\nclients. The controlled geotag place-type vocabulary uses Google Places tokens as\nits baseline plus reviewed local extensions with explicit Google fallbacks.<\/p>\n\n<p>WordPress RSS 2.0 and Atom feeds are extended with GeoRSS Simple when location\ndata is available. A post with one coordinate-bearing geotag emits a point;\nmultiple geotags emit their bounding box; posts without geotags remain ordinary\nfeed items. Geo taxonomy feeds also describe the current term at feed level. The\nserializer uses public geotag facts only and never exposes post or attachment GPS\nmeta. A server-side adapter uses WordPress <code>fetch_feed()<\/code> \/ SimplePie to convert\nexternal GeoRSS and W3C Geo feeds into GeoJSON for map clients.<\/p>\n\n<h3>External services<\/h3>\n\n<p>All external services are optional. Choosing <strong>None<\/strong> for preview maps and not\nconfiguring a lookup provider makes no external request.<\/p>\n\n<ul>\n<li><strong>Google Maps Platform<\/strong> is used only when an administrator configures a Google\nAPI key and explicitly searches for or reverse-geocodes a place in the term\neditor. The server sends the search text or clicked latitude\/longitude, selected\nlanguage\/region, and the configured API key to Google. Google Maps Platform\nTerms: https:\/\/cloud.google.com\/maps-platform\/terms\/ Privacy Policy:\nhttps:\/\/policies.google.com\/privacy<\/li>\n<li><strong>OpenStreetMap Nominatim<\/strong> is used only when an administrator selects the\npublic Nominatim provider or configures a custom Nominatim-compatible endpoint,\nthen performs a place lookup. The server sends the search text or clicked\nlatitude\/longitude to that endpoint. Public Nominatim usage policy:\nhttps:\/\/operations.osmfoundation.org\/policies\/nominatim\/ OpenStreetMap privacy\npolicy: https:\/\/wiki.osmfoundation.org\/wiki\/Privacy_Policy<\/li>\n<li><strong>Protomaps assets<\/strong> supply glyph and sprite files only when an administrator\nselects a Protomaps PMTiles preview style. The administrator's browser requests\nthe selected glyph\/sprite URLs, which disclose the browser IP address and the\nrequested map assets to Protomaps' GitHub Pages host. Protomaps legal terms:\nhttps:\/\/protomaps.com\/legal GitHub privacy statement:\nhttps:\/\/docs.github.com\/site-policy\/privacy-policies\/github-privacy-statement<\/li>\n<li><strong>MapTiler<\/strong> and <strong>Thunderforest<\/strong> are optional raster-tile providers selected\nby the site administrator. When selected, the viewer's browser requests map\ntile coordinates and sends its IP address, referrer, and the provider key in\nthe configured tile URL. MapTiler Terms: https:\/\/www.maptiler.com\/terms\/\nPrivacy Policy: https:\/\/www.maptiler.com\/privacy-policy\/ Thunderforest Terms:\nhttps:\/\/www.thunderforest.com\/terms\/ Privacy Policy:\nhttps:\/\/www.thunderforest.com\/privacy\/<\/li>\n<li><strong>External GeoRSS\/W3C Geo feeds<\/strong> are fetched only when a site administrator\nsupplies a feed URL to the server-side GeoRSS importer. The server sends the\nconfigured feed URL request to that feed's host. Its terms and privacy policy\nare determined by the feed provider selected by the site administrator.<\/li>\n<\/ul>\n\n<h3>Third-party libraries<\/h3>\n\n<p>Bundled under assets\/vendor\/, each loaded only when the matching admin preview\nprovider is active:<\/p>\n\n<ul>\n<li>Leaflet 1.9.4 (https:\/\/leafletjs.com\/, BSD-2-Clause) \u2014 raster tile previews.<\/li>\n<li>MapLibre GL JS 5.24.0 (https:\/\/maplibre.org\/, BSD-3-Clause), PMTiles 4.4.1\n(https:\/\/github.com\/protomaps\/PMTiles, BSD-3-Clause), and @protomaps\/basemaps\n5.7.2 (https:\/\/github.com\/protomaps\/basemaps, BSD-3-Clause) \u2014 PMTiles map-pack\npreviews. Label fonts load from the public Protomaps assets host.<\/li>\n<\/ul>\n\n<h3>Map strategy<\/h3>\n\n<p>Uploaded PMTiles map packs self-host the tile data, but the Protomaps renderer may\nload small glyph\/sprite assets from Protomaps' public host. Axismundi Map is a\nseparate dependent plugin: Geo Data owns the facts, REST exports, providers, and\nshared renderer assets; Map owns the public block and Query Map View. See\ndocs\/map-strategy.md for the boundary.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload and activate this plugin under any block theme.<\/li>\n<li>Posts and pages gain the Geo Area and Geotag taxonomies; attachments gain GPS\ncoordinate fields. All are available over the REST API.<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>0.2.3<\/h4>\n\n<ul>\n<li>Use unique <code>axismundi_geo_area<\/code> and <code>axismundi_geotag<\/code> taxonomy identifiers while preserving the established public archive URLs.<\/li>\n<li>Migrate pre-release term assignments to the prefixed identifiers on upgrade.<\/li>\n<li>Prefix the place-lookup transient key with the full plugin namespace.<\/li>\n<\/ul>\n\n<h4>0.2.2<\/h4>\n\n<ul>\n<li>Document every optional external service, the information it receives, and its terms and privacy links.<\/li>\n<li>Restrict anonymous attachment and GPS-track GeoJSON output to opted-in media whose actual parent post is published and publicly viewable.<\/li>\n<\/ul>\n\n<h4>0.2.1<\/h4>\n\n<ul>\n<li>Move the complete geo_area and geotag archive templates from the Axismundi theme to their Geodata domain owner.<\/li>\n<li>Preserve the current-term map, inherited card feed, and geographic navigation while allowing normal theme and user overrides.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Extend both RSS 2.0 and Atom feeds with conditional GeoRSS Simple geometry for\ngeo taxonomy feeds and posts carrying public geotag terms.<\/li>\n<li>Add a <code>fetch_feed()<\/code> \/ SimplePie adapter that normalizes external GeoRSS and\nW3C Geo feeds into bounded GeoJSON FeatureCollections for map clients.<\/li>\n<li>Preserve structured feed properties for map popups, including title, image,\nauthor, date, and excerpt, while sanitizing the only retained HTML fragment.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial foundation: geo_area + geotag taxonomies, post\/attachment coordinate\nmeta, term place-fact meta, public-coordinate gating, and REST exposure.<\/li>\n<li>Attachment Location (GPS) editor: lat\/lng\/altitude\/public fields, on-demand\nEXIF GPS import, and a Leaflet mini map with a draggable marker.<\/li>\n<li>Admin preview map settings (Settings \u2192 Geodata): none, admin-only OpenStreetMap\npreview, custom raster (XYZ) tiles, or a self-hosted uploaded PMTiles map pack\nrendered with MapLibre + the Protomaps light theme.<\/li>\n<li>Optional place lookup for geo_area \/ geotag terms through a provider registry \u2014\nGoogle Places (server-side key) and OpenStreetMap \/ Nominatim (public opt-in or\ncustom endpoint) \u2014 with explicit candidate binding to a namespaced identity.<\/li>\n<li>Controlled 508-type geotag vocabulary: Nature, Facilities, and Business,\ncombining Google Places tokens with reviewed local extensions and fallbacks.<\/li>\n<li>PMTiles map-pack metadata and preview support, GPX\/KML track recognition, and\nGeoJSON REST exports for geotags, public GPS media, and tracks.<\/li>\n<\/ul>","raw_excerpt":"Canonical geo store for Axismundi: place taxonomies and privacy-aware coordinate metadata, exposed over REST.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/343743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=343743"}],"author":[{"embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/kimjiwoon"}],"wp:attachment":[{"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=343743"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=343743"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=343743"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=343743"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=343743"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ky.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=343743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}