Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

README for Mapcode REST API Web Services

Codacy Badge Build Status Coverage Status License Release

Copyright (C) 2014-2017 Stichting Mapcode Foundation (

This application provides a REST API for mapcodes. It uses the Java Library for Mapcodes extensively. The API supports both XML and JSON (default) responses.

Warning: If you want to use this source to run a production service, always use the source version from the latest release tag. Release names are tagged "vX.Y.Z". The head of the master branch may not be stable during development.

The available REST API methods are:

All REST services (except 'metrics') are able to return both JSON and XML. Use the HTTP
'Accept:' header to specify the expected format: application/json or application/xml
If the 'Accept:' header is omitted, JSON is assumed.

GET /mapcode         Returns this help page.
GET /mapcode/version Returns the software version.
GET /mapcode/metrics Returns some system metrics (JSON-only, also available from JMX).
GET /mapcode/status  Returns 200 if the service OK.

GET /mapcode/codes/{lat},{lon}[/[mapcodes|local|international]]
     [?precision=[0..8] & territory={restrictToTerritory} & alphabet={alphabet} & include={offset|territory|alphabet|rectangle}]

   Convert latitude/longitude to one or more mapcodes. The response always contains the 'international' mapcode and
   only contains a 'local' mapcode if there are any non-international mapcode AND they are all of the same territory.

   Path parameters:
     lat             : Latitude, range [-90, 90] (automatically limited to this range).
     lon             : Longitude, range [-180, 180] (automatically wrapped to this range).

   An additional filter can be specified to limit the results:
     mapcodes        : Same as without specifying a filter, returns all mapcodes.
     local           : Return the shortest local mapcode (not an international code). Note that multiple local
                       mapcodes may exist for a location, with different territories. This method returns the
                       shortest code. It does not check if the territory is the 'geographically correct' one
                       for the coordinates. To get the shortest code for a specific territory, you need to explicitly
                       specify the territory with 'territory=' parameter in the query.
     international   : Return the international mapcode.

   Query parameters:
     precision       : Precision, range [0..8] (default=0).
     territory       : Territory to restrict results to (name or alphacode).
     alphabet        : Alphabet to return results in.
     include         : Multiple options may be set, separated by comma's:
                         offset    = Include offset from mapcode center to lat/lon (in meters).
                         territory = Always include territory in result, also for territory 'AAA'.
                         alphabet  = Always the mapcodeInAlphabet, also if same as mapcode.
                         rectangle = Include the encompassing rectangle of a mapcode.

                       Note that you can use 'include=territory,alphabet' to ensure the territory code
                       is always present, as well as the translated territory and mapcode codes.
                       This can make processing the records easier in scripts, for example.

GET /mapcode/coords/{code} [?context={territory} & include={include}]
   Convert a mapcode into a latitude/longitude pair.

   Path parameters:
     code            : Mapcode code (local or international). You can specify the territory in the code itself,
                       like 'NLD%20XX.XX' (note that the space is URL-encoded to '%20'), or you specifty the
                       territory separately in the 'context=' parameter, like 'XX.XX?context-NLD'.
   Query parameters:
     context         : Optional mapcode territory context (name or alphacode). The context is only used if the

                       code is ambiguous without it, otherwise it is ignored. For example, the context is ignored
                       when converting an international code (but it is not considered an error to provide it).
     include         : An additional option may be set:
                         rectangle = Include the encompassing rectangle of a mapcode.

GET /mapcode/territories [?offset={offset}&count={count}]
   Return a list of all territories.

GET /mapcode/territories/{territory} [?context={territory}]
   Return information for a single territory code.

   Path parameters:
     territory       : Territory to get info for (name or alphacode).

   Query parameters:
     context         : Territory context (optional, for disambiguation, name or alphacode).
                       The context can only be: USA IND CAN AUS MEX BRA RUS CHN ATA

GET /mapcode/alphabets [?offset={offset}&count={count}]
   Return a list of all alphabet codes.

GET /mapcode/alphabets/{alphabet}
   Return information for a specific alphabet.

   Path parameters:
     alphabet        : Alphabet to get info for.

General query parameters for methods which return a list of results:

   offset            : Return list from 'offset' (negative value start counting from end).
   count             : Return 'count' items at most.

Supporting XML-only Tools (e.g. Google Spreadsheets, Microsoft Excel)

The REST API methods defined above obey the HTTP Accept: header. To retrieve JSON responses, use Accept:application/json, to retrieve XML responses, use Accept:application/xml. The default response type, if no header is specified, is JSON.

Some tools, like Google Spreadheets and Microsoft Excel, can only handle XML responses, but do not provide the correct HTTP Accept: header. In these cases you can alternatively retrieve XML (JSON) responses with these alias URLs (note the "/xml" in the URLs):

GET /mapcode/xml/version           GET /mapcode/json/version
GET /mapcode/xml/status            GET /mapcode/json/status
GET /mapcode/xml/codes             GET /mapcode/json/codes
GET /mapcode/xml/coords            GET /mapcode/json/coords
GET /mapcode/xml/territories       GET /mapcode/json/territories
GET /mapcode/xml/alphabets         GET /mapcode/json/alphabets

These URLs only provide XML responses, with or without the HTTP Accept: header.

You can use these URLs, for example, in Google Spreadsheets, using the =IMPORTXML(url, xpath) function, or in Microsoft Excel 2013 or 2016 (for Windows) using the =FILTERXML(WEBSERVICE(url), xpath) functions. This should make live integration of mapcode conversion with your spreadsheets a breeze.

Build and Run

First, make sure you have the correct file encoding (UTF8) set for Java on your system. Include this environment variable in your .profile or .bashrc:

export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"

The service always runs from a WAR file. To build the WAR file, type

cd <project-root>
mvn clean install -Pprod

This will install the required JAR files in your local Maven repository (normally at ~/.m2/repository). You can run the WAR file in 3 ways:

  1. Directly from Maven using:
cd deployment
mvn jetty:run
  1. Or directly from the command-line, using:
java -jar deployment/target/deployment-<version>.war [--port <port>] [--silent] [--debug] [--help]

This will start the service at http://localhost:<port>/mapcode. If <port> is not specified, the default value is 8080. If it is 0, the server will choose any free port.

This will start the service at http://localhost:8080/mapcode.

  1. in a Tomcat server, deploying the file deployment/target/deployment-<version>.war into your Tomcat instance.

The first method, running the WAR file from the command-line, using java only is particularly useful if you wish use the XML services, for example, in a Microsoft Excel spreadsheet.

Important: If the service does not start, some files may be missing from your external-resources directory. To fix this, read on.

Missing and log4j.xml Files

The service requires 2 files called and log4j.xml to be present on the classpath. They are specifically not included in the WAR file by default, because that would make it impossible to change them without recompiling the service.


The file log4j.xml specifies the log levels during operations. An example of a log4j.xml file can be found in resources/src/main/external-resources-test/log4j.xml.

Make sure that file can be found on the classpath or add it resources/src/main/external-resources before building and it will be integrated in the WAR file.

The properties file contains the username and password for your MongDB database server for tracing, should you wish to use that.

If you get a start-up error complaining about a missing file, make sure you add it to the classpath (or add it to resources/src/main/external-resources) before building.

By default, you can simply use an empty file. So, you may want to use the example file as a starting point:

cd resources/src/main
cp external-resources-test/* external-resources/

This will copy an example log4j.xml and file to your resources.

Note that the files in external-resources are ignored by Git in .gitignore.

Using a Capped Collection for Traces in MongoDB

If you wish to use MongoDB tracing, will need to provide your own local, which override the following properties:

MongoDBTrace.writeEnabled = false
MongoDBTrace.servers = your-server:27017 (eg. localhost:27017)
MongoDBTrace.database = your-database (eg. trace)
MongoDBTrace.userName = your-username
MongoDBTrace.password = your-password

The service will work with an empty properties file as well, but will not trace events to the database.

To make sure the traces collection in the MongoDB database does not grow forever, you should create a "capped collection" for it, or convert an existing traces database to a capped collection. This can be done as follows, in the MongoDB shell mongo:

use trace
db.runCommand({"convertToCapped": "traces", size: 2*1024*1024*1024});   // For example, limit to 2Gb of data.

You can inspect the status of the trace database like this:

use trace

Using Java 8 on MacOSX

The source uses Java JDK 1.8, so make sure your Java compiler is set to 1.8, for example using something like (MacOSX):

export JAVA_HOME=`/usr/libexec/java_home -v 1.8`

Smoke Testing The REST API

Try out if the web services work by entering the following URL in your web browser (this should show you a HTML help page):


Or use a tool like cURL:

curl -X GET http://localhost:8080/mapcode
curl -X GET http://localhost:8080/mapcode/codes/50.2,4.9

There's also an example HTML page in the examples/index.html for HTML/Javascript developers.

Getting a Session Token in a Debug Session

Some REST APIs, such as GET mapcode/metrics require authentication. You can get a session on the command-line like this:

$ http post http://localhost:8080/sessions/username password=123456   

HTTP/1.1 201 Created
Content-Length: 84
Content-Type: application/json
Date: Sat, 24 Jun 2017 16:40:54 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(8.1.7.v20120910)
Set-Cookie: JSESSIONID=15j59gfek2kk9s86b8n321xzu;Path=/

    "id": "15j59gfek2kk9s86b8n321xzu",
    "personId": "00000001-0002-0003-0004-000000000005"

Then, you can pass the session token as a cookie in the HTTP request, like this:

$ http get http://localhost:8080/mapcode/metrics 'Cookie:JSESSIONID=15j59gfek2kk9s86b8n321xzu;Path=/'

HTTP/1.1 200 OK
Content-Length: 21417
Content-Type: application/json
Date: Sat, 24 Jun 2017 16:41:23 GMT
Server: Jetty(8.1.7.v20120910)

    "all": {
            "calculators": [
                    "count": 0,

Using Git and .gitignore

It's good practice to set up a personal global .gitignore file on your machine which filters a number of files on your file systems that you do not wish to submit to the Git repository. You can set up your own global ~/.gitignore file by executing: git config --global core.excludesfile ~/.gitignore

In general, add the following file types to ~/.gitignore (each entry should be on a separate line): *.com *.class *.dll *.exe *.o *.so *.log *.sql *.sqlite *.tlog *.epoch *.swp *.hprof *.hprof.index *.releaseBackup *~

If you're using a Mac, filter: .DS_Store* Thumbs.db

If you're using IntelliJ IDEA, filter: *.iml *.iws .idea/

If you're using Eclips, filter: .classpath .project .settings .cache

If you're using NetBeans, filter: nb-configuration.xml *.orig

The local .gitignore file in the Git repository itself to reflect those file only that are produced by executing regular compile, build or release commands, such as: target/ out/

Bug Reports and New Feature Requests

If you encounter any problems with this library, don't hesitate to use the Issues session to file your issues. Normally, one of our developers should be able to comment on them and fix.

Privacy Notification

The Mapcode Foundation provides an implementation of the Mapcode REST API at:

This free online service is provided for demonstration purposes only and the Mapcode Foundation accepts no claims on its availability or reliability, although we try hard to provide a stable and decent service. Note that anonymized usage and log data, including mapcodes and coordinates, may be collected to improve the service and better anticipate on its scalability needs. The collected data contains no IP addresses, is processed securely in the EEA and is never sold or used for commercial purposes. The API allows you to indicate you insist on not having data logged by the service. Please consult the API documentation for further information on how to do so. If you are interested in using the service for professional purposes, or in high-availability or high-demands contexts, you may wish to consider self-hosting this service.

Release Notes

  • Updated dependencies.

  • Corrected version to match mapcode-java library version.

  • Updated dependencies, including log4j.

  • Allowed JDK 11 and 14 ti run this application.

  • Bumped version.

  • Changed groupId to

  • Updated with correct instructions to create WAR file.

  • Updated dependencies.

  • Added reason for failure at startup in log file.

  • Updated dependencies for security vulnerabilities.

  • Updated dependencies.

  • Fixed jackson-databind security issues.

  • Improved handling if incorrect coordinates and parameter values, producing a HTTP 400 Bad Request rather than HTTP 404 Not Found. –

  • Updated Mapcode library.

  • Updated dependency versions (for bug fixes and security pacthes).

  • Updated copyright.

  • Updated dependency version (for bug fixes and security pacthes).

  • Changed web.xml to disallow anything but GET and HEAD requests.

  • Added ?country= parameter for mapcode encoding, to limit the result list to a specific country, given as a 2- or 3-character ISO 3166 country code. (In contrast with ?territory=, which is not always a country, but can be a state as well.) -

  • Updated to new Mapcode library.

  • Added testcase for .../mapcodes.

  • Removed unused code. -

  • Updated library dependencies.

  • Moved to Mapcode Java library 2.4.5. No functional changes. -

  • Improved status call to actually do a mapcode conversion back and forth.

  • Improved Swagger documentation.

  • Split JSON- and XML-only calls into seperate files.

  • Note that was broken, fixed by -

  • Added Swagger documentation to the API's. Swagger generates online API documentation, with the ability to try out the API.

  • Added include=rectangle parameter to retrieve the encompassing rectangle of a mapcode.

  • Upgraded to Mapcode Library 2.4.4. -

  • Updated dependency on SpeedTools.

  • Implemented security for REST calls.

  • Updated all copyright notices.

2.4.2 - 2.4.3

  • Updated dependencies.

  • Increased test coverage, using Mockito stubs.

  • Fixed JSON response for REST example.

  • Removed secret token from POM.

  • Added scripts for Tifinagh (Berber), Tamil, Amharic, Telugu, Odia, Kannada, Gujarati.

  • Added alphabets element to territories, returning the most commonly used languages for the territory.

  • Renamed constant HINDI to DEVANAGIRI.

  • Improved some characters for Arabic and Devanagari.

  • Fixed Bengali to also support Assamese.

  • Updated to new Java library 2.4.0 with new scripts support.

  • Updated to new Java library version 2.3.1 (fixed data in some part of China).

  • Important release, which includes full Arabic support and changes the way some other alphabets work (including Greek and Hebrew).

  • Added client= parameter, to allow logging per client type.


  • Changed semantics of /mapcode/codes/{lat,lon}/local to always get the shortest code, even if the territory may be ambiguous.

  • Added explanatory text in help text for REST API.

  • Added Travis CI and Coveralls badges to

  • Increase test coverage, added unit tests.

  • Updated to Java library 2.2.4.

  • Cleaned up POM, sorted dependencies.

  • Updated to SpeedTools 3.0.21 which uses a more recent JBoss RESTEasy framework.

  • Reworked responses for /alphabets and /territories, returning to older format (also easier for client parsing) and including a total attribute to indicate total number of items in list (for paging).

  • Added metrics for alphabets and territories methods.

  • Completely refactored the source tree to create JARs for all classes in the WAR file. This was needed to allow running the service from the command-line using java only.

  • This version can be used to run the service stand-alone, without Tomcat, on a local machine. This allows you, for example, to use the XML services from within your own local MS Excel sheet. -

  • Changed JSON API response for /alphabets and /territories: these no longer return a top-level entity alphabets or territories; only the list of values, which is more in line with the rest of the API.

  • Added help text.

  • Removed Docker profile for now (might be re-added later), as it caused some issues building the service.

  • Added additional XML support. You can prefix methods now with xml, to make the default output XML, rather than JSON. This is particularly useful if you need to use an XML service, but you can't specify the correct HTTP header.

  • Works with Google spreadsheets and Microsoft Excel.

  • In Google spreadsheets use the =IMPORTXML function, e.g. =IMPORTXML(",4.908543";"//local")

  • In Microsoft Excel, use the =WEBSERVICE function.

  • Added full XML support, next to JSON. Use the HTTP Accept header to specify the expected format: application/json or application/xml. (This features allows users of MS Excel to use the =WEBSERVICE() function, on Windows.)

  • Added unit tests to test the REST services.

  • Added debug mode, which prevents writing to the trace database.

  • Fixed content type on GET operations to accept anything. -

  • Based on new version of the Java library. Includes high-precision codes, up to precision 8.

  • Based on version 2.0.2 of the Java library.

  • Based on version 2.0.1 of the Java library (which is Java 6 again, from Java 8).

  • Typo in startup LOG message fixed.

  • Allows to use territory names, as well as territory codes.

  • Based version 2.0.0 of the Java library.

  • Includes fixes and enhancements to data. For a complete description, read the Word file that ships with the C version of the library (on Github).

  • This version no longer supports numeric codes for territories and alphabets.

  • Changed property names in REST API for territories: code is renamed to number, name is renamed to alphaCode.

  • The decode service now only returns local mapcode if all local mapcodes are within the same territory.

  • The decode service produces a 404 if you ask for a local code exists and none exists, or multiple exist in different territories. -

  • Updated Java library for Mapcode.

  • Added include=alphabet option to always include mapcodeInAlphabet or territoryInAlphabet even if the same as the original (default is now these are only output if different). -

  • Bug fix for state IN-DD (in India).


  • First release of the REST API, based on the Mapcode Java library, version 1.50.0.