NAV Navbar
Wrapper PHP

Introduction

Welcome to the API documentation for Maps4News.

Our API allows you to manage everything about your Maps4News account and your organisation. As well as generate Maps.

Authentication

To authorize, use this code:

import { ImplicitFlow, Maps4News } from '@mapcreator/maps4news';

const API_CLIENT_ID = 0;
const API_HOST = 'https://api.maps4news.com';
const REDIRECT_URL = 'http://localhost/';

const auth = new ImplicitFlow(API_CLIENT_ID, REDIRECT_URL);
const api = new Maps4News(auth, API_HOST);

// Somewhere in your application
api.authenticate();

// Get the user's information
api.users.get('me').then(console.log);
This example uses the guzzlehttp package from Composer.

<?php

$host = "https://api.maps4news.com/v1";
$client_id = 0;
$secret = "secret";
$redirect_uri = "http://localhost/callback";

////////////////////////////
// /login route in your app.

// Prepare redirect to API login page.
$query = http_build_query([
    'client_id' => $client_id,
    'redirect_uri' => $redirect_uri,
    'response_type' => 'code'
]);

// Redirect user.
header("Location: $host/oauth/authorize?$query");

//////////////////////////////
// /callback route in your app.

$http = new GuzzleHttp\Client();

// Get the user's access_token.
$response = $http->post("$host/oauth/token", [
    'form_params' => [
        'grant_type' => 'authorization_code',
        'client_id' => $client_id,
        'client_secret' => $secret,
        'redirect_uri' => $redirect_uri,
        'code' => $_POST['code']
    ]
]);

// Get the access token.
$token = json_decode((string) $response->getBody(), true)['access_token'];

// Request the user's info.
$response = $http->get("$host/v1/users/me", [
    'headers' => [
        'Authorization' => "Bearer $token",
        'Accept' => 'application/json'
    ]
]);

// Display the user's information
print_r(json_decode((string) $response->getBody()));

Make sure the client_id, host and redirect_url are correctly filled in.

The Maps4News API is an OAuth2 API. We support implicit and password flows.

API

To register an OAuth Client or Personal Access Token, please log into the API and register one via your account settings.

Have a look at our OpenAPI spec, the spec contains all the endpoints & info about how resources look and what each endpoint requires you to submit.

To Log in and try it out hit the "Try out" button.

Return Data

For success responses

{
  "success": true,
  "data": {
    ...
  }
}

For error responses

{
  "success": false,
  "error": {
    "type": "HttpNotFoundException",
    "message": "Page Not Found"
  }
}

For error responses with validation errors

{
  "success": false,
  "error": {
    "type": "ValidationException",
    "message": "Input data failed to pass validation",
    "validation_errors": {
      "attribute": [
        "validation error for the attribute"
      ]
    }
  }
}

For error responses with JSON schema errors (current only used when creating a Job Revision)

{
  "success": false,
  "error": {
    "type": "ValidationException",
    "message": "Input data failed to pass validation",
    "validation_errors": {
      "attribute": [
        "validation error for the attribute"
      ]
    },
    "schema_errors": [
      {
        "property": "data.meta",
        "pointer": "/data/meta",
        "message": "The propery meta is required",
        "constraint": "required",
        "context": 1
      }
    ]
  }
}

All JSON responses from the API are wrapped in a base object.

Be sure to include an Accept: application/json header, otherwise, errors like 401, 403 & 404 will either return HTML or redirect you to the login page.

Headers

Exposed Headers

For Pagination

See pagination

For HTTP Caching

Create Route

/v1/users

Update Route

/v1/users/1

All returned model resources have an ETag and Last-Modified header.

ETag headers are returned from Get, Create & Update requests. Because the ETags are weak they can also be used on other routes.

For example, when getting a resource the API will return an ETag header, the value of that ETag header can be used on the update route prevent the lost update problem.

Exposed CORS Headers

Accepted Headers

For Pagination

See pagination

For Midair Collision Prevention

We follow the standard as described on the Mozilla Developer Network.

If you submit any of these headers the API will assume you only want to update a resource when the header condition is met, omit these if you do not care about preventing the lost update problem

Query Parameters

The API has a few query parameters available that you can use to help find the resources you need.

All of these query parameters are only available on listing endpoints, so endpoints that return an array of items.

Pagination

As Query Parameter

?page=1&per_page=50&offset=0

As Header

X-Page: 1
X-Per-Page: 50
X-Offset: 0

By default, the API returns 12 items per page and defaults to page 1.

The number of items per page can be increased to a maximum of 50 items.

Offset

offset is a special parameter within our pagination system, the offset will remove the first n items from the list you are querying. offset can be used to work around getting duplicate data.

So, for example: if the list has 600 items and the offset is set to 100, the X-Paginate-Total will report 500 items, other headers like X-Paginate-Pages will also be calculated from the new total.

Sorting

Sort ID descending and name ascending

?sort=-id,name

The API supports sorting ascending or descending sorting on multiple columns (separated by a comma) on the resources.

Sortable columns are whitelisted inside the API, look in the model list below for supported columns

Searching

Search for name LIKE "Kevin" and company that ends with "4News"

?search[name]=Kevin&search[company]=$:4News

Searching can be done on multiple columns, we use the URL array syntax for this.

The basic syntax is operator:value, so: =:4News

The same is for searchable columns, these are whitelisted per resource

The available operators are:

Keywords

There are a few keywords throughout the API that you can use in the URL as shortcuts to certain resources.

GET /v1/users/me

For example, you can use me as a keyword for a user. This will return the resource of the user that that is associated with the token used to make the request.


GET /v1/organisations/mine

A manager can use the mine keyword to get a list of organisations he/she manages.


GET /v1/jobs/1/revisions/last

To get the last revision for a job, you can use the last keyword.

Wrapper

You can install the library using:

npm install @mapcreator/maps4news

If you are using JavaScript to develop your app then you are in luck. We have created a query builder-like library that is able to do everything our API offers. It even does the OAuth login for you, in redirect, popup or password flow.

The library is freely available on github and npm.

Have a look at the Wrapper's ESDoc API documentation.

Installation

// Using npm
npm install --save @mapcreator/maps4news

Installation can be done either through a node package manager, such as npm or yarn, or by including the browser bundle.

NodeJS

var m4n = require('@mapcreator/maps4news');

// Do stuff
var auth = new m4n.ImplicitFlow(1);
var api = new m4n.Maps4News(auth);

After installation the package can be imported as follows



ES6

import { Maps4News, DummyFlow } from '@mapcreator/maps4news';

// Do stuff
var auth = new DummyFlow();
var api = new Maps4News(auth);

Or when using ES6 import statements



Browser Script Tag

<script src="https://unpkg.com/@mapcreator/maps4news/dist/bundle.browser.min.js"></script>

This html tag can be used without any other dependency in your html.

const { Maps4News, DummyFlow } = window.maps4news;

// Do stuff
var auth = new DummyFlow();
var api = new Maps4News(auth);

You can also include the wrapper via a script tag in your html file.

Authentication

Authentication is done through OAuth. This library provides multiple OAuth flow implementations for authentication. The client will first check if any tokens can be found in the cache before requiring authentication. If one can be found the api.authenticate() method will instantly resolve without any side-effects. The variable api.authenticated will be set to true if a token has been found and is still valid.

Tokens are stored in HTTPS cookies if possible and using localStorage when the browser is not using a HTTPS connection. NodeJS uses a file named .m4n_token to store the token.

Authentication Web

Multiple flows are supported for web browsers. All the web examples assume the web build of the library has been included in the target page.

Machine token

const token = "...";
const api = new Maps4News(token);

A machine token can be used directly while instantiating the api instance.

Implicit flow

// Obtained client id
var clientId = 1;

// Callback url is set to the current url by default
var auth = new ImplicitFlow(clientId);
var api = new Maps4News(auth);

// This will hijack the page if no authentication cache can
// be found. Smartest thing to do is to just let it happen
// and initialize any other code afterwards.
api.authenticate().then(function() {
  // Save the token
  api.saveToken();

  // Get the current user and dump the result to the console.
  api.users.get('me').then(console.dir);
});

A client id is required to use the implicit flow. The redirect url must be the same as the one linked to the client id. The callback url is automatically guessed if none is provided.

Implicit flow pop-up

index.html

var clientId = 1;
var callbackUrl = 'https://example.com/callback.html';

var auth = new ImplicitFlowPopup(clientId);
var api = new Maps4News(auth);

api.authenticate().then(function() {
  // Save the token
  api.saveToken();

  // Get the current user and dump the result to the console.
  api.users.get('me').then(console.dir);
});

callback.html

<html><body>
  <h1>Nothing to see here 👻</h1>
</body></html>

This will create a pop-up window containing the login page. Once the pop-up redirects back to the callback it will resolve the promise. The callback can be an empty page hosted on the same domain.

Callback url is set to the current url by default. The script is smart enough close the page if it detects that it's a child after authentication. This means that either the current page can be set as the callback (default) or a blank page. The callback must be hosted on the same domain as the application to allow for cross window communication.

Dummy flow

var auth = new DummyFlow();
var api = new Maps4News(auth);

// Manually check if we're logged in
if (api.authenticated) {
    console.log('Found authentication token in cache!');
}

api.authenticate().then(function() {
    // Will only resolve if a token was found
    console.log("We're authenticated");
}).catch(function(err) {
    // This will be called if `api.authenticated` is false
    console.log(err.toString());
});

The dummy flow can be used when a token should be present in the cache.

Basics

These examples assume that an instance of the api exists and is authenticated. See the node and web authentication examples for more information on authenticating.

const me = await api.users.get('me');
const colors = await me.colors.list();

Which is the same as

const colors = await api.users.select('me').colors.list();

The wrapper exposes relations which return proxies. These proxies can be used to either build a route to a resource or to fetch resources.

This means that api.users.get('me') is the same as calling the route /v1/users/me.

All proxies expose the methods new, list and lister. Most proxies expose the methods select and get.

Async methods return a Promise this means that both then/catch and await/async syntax are supported.

// Case translation
const data = {
  foo_bar_baz: 123
};

const test = api.static().new(data);

test.fooBarBaz === 123; // true

The wrapper will transform snake_case named variables returned from the api into camelCase named variables. This means that for example place_name will be transformed into placeName.

Getting a resource

Fetch resource and all its properties

api.colors.get(1).then(function(color) {
    console.log(color.id + " " + color.name + ": " + color.hex);
});

Select the current user to quickly obtain related mapstyle sets

api.users.select('me').mapstyleSets.list().then(function(sets) {
    for (const set of sets.data) {
        console.log(`[${set.id}] ${set.name}`);
    }
});

Resources are bound to the base api class by default. Resources can be fetched in two ways; by selecting them (.select) or by fetching them (.get).

Selecting them will only set the object's id to its properties. Fetching a resource returns a Promise that will resolve with the requested resource.

Selection is only useful as a stepping stone to related resources that can be easily obtained using the id of the parent.

Please refer to the api documentation for further reference.

Create a new resource

var data = { name: 'Smurf', hex: '88CCFF' };
api.colors.new(data).save().then(console.dir);

Create a new color and dump the new resource to the console after saving

Modify a resource

api.users.get('me').then(me => {
  me.profession = 'Developer';

  me.save(); // Optional chaining to get the updated resource
});

Change profession of the current user and save it.

Clone a resource

api.colors.get(1).then(color => {
  color.id = null;
  color.save();
});

Setting the id to null forces the creation of a new object upon saving.

Pagination

Listing resources with pagination. First page with 5 items per page

api.colors.list(1, 5).then(page => {
  console.log('Got resources:');

  for (var i = 0; i < page.data.length; i++) {
    console.log(page.data[i].toString());
  }
});

Loop over every page and print the result to the console

function parsePages(page) {
  for (var i = 0; i < page.data.length; i++) {
    console.log(page.data[i].toString());
  }

  if (page.hasNext) {
    console.log('Grabbing page ' + (page.page + 1));
    page.next().then(parsePages);
  }
}

api.colors
   .list(1, 50)
   .then(parsePages);

Loop over all pages and return the data in a promise

function parsePages(page) {
  var data = [];

  function parse(page) {
      data = data.concat(page.data);

      if(page.hasNext) {
          return page.next().then(parse);
      } else {
          return data;
      }
  }

  return parse(page);
}

api.colors
   .list(1, 50)
   .then(parsePages)
   .then(d => console.log('Total rows: ' + d.length));

Select current user but do not fetch any info to make fetching resources easier

api.users.select('me').colors.list().then(page => {
  console.dir(page.data);
});

warning: The paginatedResourceListing is in the progress of being deprecated.

Searching

Resource lists can be queried to search for specific records as follows

var query = {
  name: '^:test',
  scale_min: ['>:1', '<:10'],
}

api.layers.search(query).then(console.dir);

deprecated - Will change soon.

The search method is an extension of list. This means that .search({}) is the same as list(). More information about search query formatting can be found in the api documentation.

Examples

Building a Map

Prerequisites:

Notes:

To build a map via our system, you first need to create a few resources.

const api = new Maps4News(token);

// 1. Job
const job = await api.jobs.new({
  jobTypeId: 7,
  title: 'My Map'
}).save();

// 2. Job Revision
import * as mapObject from './map.json'; // NodeJS

const revision = await job.revisions.new({
  languageCode: 'eng',
  mapstyleSetId: 60 // Here Mapstyle
}).save(mapObject);

// 3. Building
const build = await revision.build('http://example.com/callback');

// 4. Job Result
const result = await revision.result();

// 5. Getting the preview
const preview = await result.downloadPreview();

window.location = preview;
<?php

$http = new GuzzleHttp\Client([
    'base_uri' => 'https://api.maps4news.com',
    'headers' => [
        'Authorization' => "Bearer $token",
        'Content-Type' => 'application/json',
        'Accept' => 'application/json',
    ],
]);

// 1. Job
$jobResponse = $http->post('v1/jobs', [
    GuzzleHttp\RequestOptions::JSON => [
        'job_type_id' => 7, // API Map
        'title' => 'My Map',
    ],
]);

$job = json_decode($jobResponse->getBody());

// 2. Job Revision
$mapObject = file_get_contents('./map.json'); // As a string

$revisionResponse = $http->post("/v1/jobs/$job->id/revisions", [
    GuzzleHttp\RequestOptions::JSON => [
        'language_code' => 'eng',
        'mapstyle_set_id' => 60, // Here Mapstyle
        'object' => $mapObject,
    ],
]);

$revision = json_decode($revisionResponse->getBody());

// 3. Building
$buildResponse = $http->post("/v1/jobs/$job->id/revisions/$revision->revision/build");

$build = json_decode($buildResponse->getBody());

// 4. Job Result
$resultResponse = $http->get("/v1/jobs/$job->id/revisions/$revision->revision/result");

$result = json_decode($resultResponse->getBody());

// 5. Getting the Preview
$previewResponse = $http->get("/v1/jobs/$job->id/revisions/$revision->revision/result/preview");

header('Content-Type: image/png');
echo $previewResponse->getBody();

Steps



A Revision requires us to give it a language_code, these are 3 character strings, (eng, ger, ita, dut, etc.) as well a mapstyle_set_id and the map json as a string.

(A list of available mapstyle sets can be gotten from /users/me/mapstyle-sets)

A map object must be given to each revision. Revisions can not be updated, each save will result in a new revision.

Details about how to make a map object can be found on the map object page.




The Final Result

Map Preview

Models

Choropleth

Attribute Type Description Searchable Sortable
id integer The choropleth id No No
description string The description of the choropleth Yes Yes
json_filename string The json file name of the choropleth Yes No
preview_filename string The preview file name of the choropleth Yes No
version string The version identifier for the choropleth Yes Yes
projection_systems array nullable JSON Array of used projection systems Yes No
ratio integer 0 to 1, the percentage that the choropleth matches the given boundary Yes Yes

Color

Attribute Type Description Searchable Sortable
id integer The color id No Yes
name string The name of the color Yes Yes
hex string The hex value of the color Yes Yes

Contract

Attribute Type Description Searchable Sortable
id integer The contract id No Yes
organisation_id integer The id of the owner No No
name string The name of the contract Yes Yes
auto_renewal boolean If the contract should be automatically renewed Yes Yes
date_start string The start date of the contract Yes Yes
date_end string The end date of the contract Yes Yes

Dimension

Attribute Type Description Searchable Sortable
id integer The dimension id No Yes
dimension_set_id integer The id of the dimension set No No
name string The name of dimension Yes Yes
width number The width of the dimension Yes Yes
height number The height of the dimension Yes Yes
dpi number The dpi of the dimension No No

DimensionSet

Attribute Type Description Searchable Sortable
id integer The dimension set id No Yes
name string The dimension set name Yes Yes

Faq

Attribute Type Description Searchable Sortable
id integer The id of the question No Yes
question string The question text Yes Yes
answer string The answer of the question Yes Yes

Feature

Attribute Type Description Searchable Sortable
id integer The feature id No No
name string The feature name Yes Yes
description string The description of the feature Yes Yes

Font

Attribute Type Description Searchable Sortable
id integer The id of the Font No Yes
font_family_id integer The id of the font family No No
name string The name of the font Yes Yes
style string The font style Yes Yes
weight integer The font weight No No
label string The label of the font Yes Yes

FontFamily

Attribute Type Description Searchable Sortable
id integer The id of the font family No Yes
name string The name of the font family Yes Yes

Highlight

Attribute Type Description Searchable Sortable
geojson object The geojson for the highlight No No

InsetMap

Attribute Type Description Searchable Sortable
id integer The InsetMap id No No
description string The description of the InsetMap Yes Yes
json_filename string The json file name of the InsetMap Yes No
lat_min integer The minimum latitude for the insetmap No No
lng_min integer The minimum longitude for the insetmap No No
lat_max integer The maximum latitude for the insetmap No No
lng_max integer The maximum longitude for the insetmap No No

Job

Attribute Type Description Searchable Sortable
id integer The job id No Yes
job_type_id integer The id of the job type Yes No
user_id integer The user id Yes No
title string The title of the job Yes Yes
description string The description of the job Yes Yes
share_token string The token used for sharing this job No No

JobResult

Attribute Type Description Searchable Sortable
job_revision_id integer The id of the job revision No No
mapstyle_id integer The id of the map style No No
interface_version string The version of the interface Yes Yes
fix string No No
status string The status of the job result Yes Yes
fail_reason string A human-readable reason of why the map failed to process No No
process_start string The datetime when the job process started Yes Yes
process_end string The datetime when the job process ended Yes Yes
dealt_with boolean Checks if the Support fixed an issue of the job result Yes Yes
bought boolean Checks if the result is bought or not Yes Yes
contract_id integer The id of the contract that was active when the map was created No No
callback string URL to another API which can finish the map Yes Yes
last_downloaded string The last time the archive was downloaded Yes Yes

JobRevision

Attribute Type Description Searchable Sortable
id integer The id of the job revision No Yes
job_id integer The id of the job related to this revision Yes Yes
revision integer The revision number Yes Yes
language_code string The language code of the revision Yes Yes
mapstyle_set_id integer The id of the mapstyle set No No
archived boolean Whether the revision has been generated and therefore archived Yes Yes

JobShare

Attribute Type Description Searchable Sortable
id integer The id of the job share No Yes
job_revision_id integer The id of the job revision related to this share No No
visibility string The visibility of the job share Yes Yes
hash_key string The hash key of the job share No No

JobType

Attribute Type Description Searchable Sortable
id integer The id of the job type No Yes
name string The name of the job type Yes Yes
preview string The preview file name of the job type No No
description string The description of the job type Yes Yes
components string The components of the job type No No

Language

Attribute Type Description Searchable Sortable
code string The language code No No
name string The name of the language Yes Yes
locale string The locale string for the language Yes Yes
interface boolean If this language can be used for user interfaces Yes Yes

Layer

Attribute Type Description Searchable Sortable
id integer The id of the layer No Yes
name string The name of the layer Yes Yes
path string The path to the layer No No
description string The description of the layer Yes Yes
image string The image related to a layer No No
scale_min integer The minimum number of the scale for the layer Yes Yes
scale_max integer The maximum number of the scale for the layer Yes Yes
pangaea_ready boolean Flag to indicate wether a layer is prepared for Pangaea Yes Yes

Mapstyle

Attribute Type Description Searchable Sortable
id integer The id of the mapstyle No Yes
mapstyle_set_id integer The id of the set related to this mapstyle No No
name string The name of the map style Yes Yes
scale_min integer The minimum value of the scale for the map style Yes Yes
description string description of the map style Yes Yes

MapstyleSet

Attribute Type Description Searchable Sortable
id integer The id of the mapstyle set No Yes
name string The name of the mapstyle set Yes Yes
description string The description of the set Yes Yes
supports_svg boolean If the set supports svg Yes Yes
locator_ready boolean If the set can be used as locator Yes Yes
show_underlying_elements boolean Shows elements even if behind annotations No No
job_type_id integer The id of the job type Yes No
preview_lat integer The latitude for the preview image No No
preview_lon integer The longitude for the preview image No No
preview_language_code string The language code of the preview No No
world_cache integer The name of the world cache No Yes
world_cache_max_zoom integer The max zoom level of the world cache No Yes
css string Custom CSS for the MapstyleSet No Yes

Notification

Attribute Type Description Searchable Sortable
id integer The id of the notification No Yes
title string The title of the notification Yes Yes
message string The notification message Yes Yes

OneTimeLoginToken

Attribute Type Description Searchable Sortable
user_id integer The id of the user that the token belongs to No No
creator_id integer The id of the user that created the token No No
token string The 30 character token to login with via /login/one-time/{token} No No
used_at date The possibly null date that the token is used at No No
expires_at date The date that the token will expire at No No

Organisation

Attribute Type Description Searchable Sortable
id integer The id of the organisation No Yes
name string The name of the organisation Yes Yes
manager_id integer The id of the manager of the organisation Yes No
sales_representative_id integer The id of the sales representative of the organisation Yes No
credits integer The credits of the organisation Yes Yes
country string The country where the organisation is from Yes Yes
address string The address of the organisation Yes Yes
city string The city of the organisation Yes Yes
settings object An object with settings for the organisations No No
vector_token string The vector API token of the organisation No No

OrganisationInvitation

Attribute Type Description Searchable Sortable
organisation_id integer The id of the organisation that this invitation is for No No
creator_id integer The id of the user that created this invite No No
code string A randomly generated string that holds the invitation code No No

Permission

Attribute Type Description Searchable Sortable
id integer The id of the permission No Yes
name string The name of the permission Yes Yes

SingleSignOn

Attribute Type Description Searchable Sortable
user_id integer The id of the user No Yes
sso_id integer The id of SSO No Yes
type string The type of the SSO Yes Yes

Svg

Attribute Type Description Searchable Sortable
id integer The id of the svg No Yes
svg_set_id integer The id of the svg_set related to this svg No No
name string The name of the svg Yes Yes
string string The XML of the svg No No
resize_factor number The number of the resize for svg Yes Yes

SvgSet

Attribute Type Description Searchable Sortable
id integer The id of the set No Yes
name string The name of the set Yes Yes
type string The type of the svg set Yes Yes
supports_interactive boolean If the set is interactive Yes Yes

Tag

Attribute Type Description Searchable Sortable
id integer The tag id No Yes
name string The name of the tag Yes Yes
description string The description of the tag Yes Yes

User

Attribute Type Description Searchable Sortable
id integer The id of the user No Yes
language_code string The language of the user No No
organisation_id integer The id of the organisation related to a user Yes No
name string The name of the user Yes Yes
email string The email of the user Yes Yes
phone string The phone of the user Yes Yes
profession string The user's profession Yes Yes
company string The user's company No Yes
country string The user's country No Yes
city string The user's city No Yes
address string The user's address No Yes
tips boolean If the user wishes to see tips No No
tags string The tags related to a user Yes Yes
confirmed boolean Whether the user is verified No No
notifications_checked_at string The datetime when the user checked the notifications No No
referral string The referral code that the user used during their registration No No