Converts geojson to svg string given svg viewport size and maps extent.

Related tags

Maps svg map geojson
Overview

geojson2svg

Converts geojson to svg string given svg viewport size and maps extent.

Check world map, SVG scaled map and color coded map examples to demonstrate that its very easy to convert geojson into map.

Installation

Using in node.js or with browserify

npm install geojson2svg

For including in html page standard way, download file dist/geojson2svg.min.js

<script type="text/javascript" src="path/to/geojson2svg.min.js"></script>

This creates a global variable 'geojson2svg'

geojson2svg is also available on cdnjs and can be included like:

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/geojson2svg/x.x.x/geojson2svg.min.js"></script>

Usage

Using in node.js or with browserify

var geojson2svg = require('geojson2svg');
var converter = geojson2svg(options);
var svgStrings = converter.convert(geojson,options);

Using in browser standard way

var converter = geojson2svg(options);
var svgStrings = converter.convert(geojson,options);

convert function returns array of svg element string

Now svg strings can be easily converted to HTML svg elements. Intentionally I have kept the geojson2svg's output as string to make it more modular. Here is simple way to convert svg strings to svg elements with parse-svg or with any other parser.

npm install parse-svg

or include in your html file

<script type="text/javascript" src="path/to/parse-svg.min.js"></script>

Simple way to convert svgStrings to svg elements

var parseSVG = require('parse-svg')
var svgElements = svgStrings.map(function(svgString) {
  return parseSVG(svgString)
})

Options

  • viewportSize is object containing width and height in pixels. Default viewportSize values are:
  {
    width: 256,
    height: 256
  }
  • mapExtent: {"left": coordinate, "bottom": coordinate, "right": coordinate, "top": coordinate}. Coordinates should be in same projection as of geojson. Default maps extent are of Web Mercator projection (EPSG:3857). Default extent values are:
  {
    left: -20037508.342789244,
    right: 20037508.342789244,
    bottom: -20037508.342789244,
    top: 20037508.342789244
  }
  • output: 'svg'|'path' default is 'svg'

    'svg' - svg element string is returned like '<path d="M0,0 20,10 106,40"/>'

    'path' - path 'd' value is returned 'M0,0 20,10 106,40' a linestring

  • fitTo 'width' | 'height' Fit ouput svg map to width or height.

  • explode: true | false, default is false. Should multigeojson be exploded to many svg elements or not.

  • attributes: Attributes which are required to attach as SVG attributes from features can be passed here as list of path in feature or json object for static attributes, like shown here

    dynamic {"attributes": ["properties.foo", "properties.bar"]}

    output: [<path foo="fooVal-1" bar="barVal-1" d="M0,0 20,10 106,40"/>]

    or static {"attributes": {"class": "mapstyle"}}

    outut: '<path class="mapstyle" d="M0,0 20,10 106,40"/>'

    or dynamic and static both

    {attributes: [
      {
        property: 'properties.foo',
        type: 'dynamic',
        key: 'id'
      }, {
        property: 'properties.baz',
        type: 'dynamic'
      }, {
        property: 'bar',
        value: 'barStatic',
        type: 'static'
      }]
    })
    

    output: [ '<path d="M128,128 128.00638801979818,127.99361198020182" id="fooVal-1" baz="bazVal-1" bar="barStatic"/>']

    Note: If a feature does not have value at the mentioned path then the attribute key would not be attached to svg string and even error would not be thrown.

  • pointAsCircle: true | false, default is false. For point geojson return circle element for option: { "pointAsCircel": true } output svg string would be:

    '<cirlce cx="30" cy="40" r="1" />'

  • r: radius of point svg element

  • callback: function, accept function that will be called on every geojson conversion with output string as one input variable e.g:

    { "callback": function(svgString) {
      // do something with svgString
    }}
    

    Callback function could be used to render SVG string.

The options 'attributes', 'r' and 'callback' can also be given in convert function

var svgStrings = convertor.convert(geojson, 
  {
    "attributes": ...,
    "r": ...,
    "callback": function
  }

mapExtent is critical option default are the extents of Web Mercator projection ('EPSG:3857') or also known as Spherical Mercator. This projection is used by many web mapping sites (Google / Bing / OpenStreetMap). In case your source data is in geographic coordinates, it can be converted on the fly to Web Mercator Projection using reproject-spherical-mercator or reproject or proj4js. Check my world map example for detail.

Assigning id to SVG path

There are three ways for doing this. First and second, .converter reads it from feature.properties.id or feature.id. Third way, pass id along with attributes like converter.convert(feature, {attributes: {id:'foo-1', class: 'bar'}}). Preference order is first as id key in attributes then feature.id and last feature.properties.id.

Examples

Converts geojson LineString to svg element string:

var converter = geojson2svg(
  {
    viewportSize: {width: 200, height: 100},
    mapExtent: {left: -180, bottom: -90, right: 180, top: 90},
    output: 'svg' 
  }
);
var svgStrings = converter.convert(
  {type:'LineString',coordinates:[[10,10],[15,20],[30,10]]}
);
//svgStrings: ['<path d="M105.55555555555556,44.44444444444444 108.33333333333333,38.888888888888886 116.66666666666666,44.44444444444444" />']

Converts geojson Polygon to svg path data 'd' string:

var converter = geojson2svg(
  {
    viewportExtent: {width: 200, height: 100}, 
    mapExtent: {left: -180, bottom: -90, right: 180, top: 90},
    output: 'path'
  }
);
var pathData = converter.convert(
  {
    "type": "Polygon", 
    "coordinates": [
      [[30, 10], [40, 40], [20, 40], [10, 20], [30, 10]] 
    ]
  }
);
// pathData: ['M116.66666666666666,44.44444444444444 122.22222222222221,27.77777777777778 111.11111111111111,27.77777777777778 105.55555555555556,38.888888888888886 116.66666666666666,44.44444444444444Z']

Check my blog maps-on-blackboard for more detailed examples.

Developing

Once you run

npm install

then for running test

npm run test

to create build

npm run build

##License This project is licensed under the terms of the MIT license.

Comments
  • Support for custom data properties

    Support for custom data properties

    We have a use-case for assigning custom properties to SVGs based off GeoJSON properties. I've quickly pulled together this which might need some tweaking and happy to take some feedback. Couple of points up for discussion:

    1. I chose properties.data of geojson feature as a namespace for any custom props. That key name might need to be more explicit (maybe customData)
    2. I didn't include any validation for SVG foreign namespace spec https://www.w3.org/TR/SVG/extend.html#ForeignNamespaces. Is it ok to put that responsibility on the user?
    opened by willmcclellan 11
  • Add attributes from Geojson to SVG

    Add attributes from Geojson to SVG

    Hello,

    Can we add some attributes from Geojson to SVG, with providing which properties or geometries in Geojson we need to add in SVG, with "geojson2svg"?

    opened by Mohsen62m 7
  • attributes again

    attributes again

    hi @gagan-bansal,

    Thanks a lot for the merge. I have one question, currently you allow either attributes by properties or by passing a json object, which mean I can't use both (in my case I need both), could this behavior change to something like

    {
        "attributes": {
            static: {"class": "mapstyle"},
            dynamic: ["properties.foo", "properties.bar"]
        }
    }
    

    I'm sorry if I didn't mention this earlier, but the other branch used to read the property data and add its content as attributes, which allowed me to use both. I didn't read your source code yet, so I could be missing something.

    Thanks!

    opened by allochi 4
  • Zoom in to geojson

    Zoom in to geojson

    Hi,

    I have a small route around a town that I am trying to convert to an SVG. How would I expand this to fix the viewport. It is currently a tiny spec.

    Thanks, Rob

    opened by robmarshall 3
  • Coordinate dimensions other than XY fails

    Coordinate dimensions other than XY fails

    It seems like the only coordinate dimensions that work are XY (not e.g. XYZ, XYM). Not sure this that is a bug or a feature not yet implemented. For XYZ- coordinates the script fails with the error TypeError: coordinates.map is not a function at /reproject/index.js:13:22

    opened by rotsee 3
  • Dynamic attributes

    Dynamic attributes

    Thanks for a handy lib! It would be really nice id it was possible to assign attributes depending on some geojson data, either by mapping json attrubites to SVG attributes, or by passing the relevant json attribute to the callback function, so that something like the following was possible:

    {"type":"Feature","properties":{"ID":"foo"},"geometry":{"type":"MultiPolygon","coordinates":...
    

    =>

    <path data-id="foo" d="...
    
    opened by rotsee 3
  • How to input a geojson file

    How to input a geojson file

    I have a geojson file, and I used fs.read() to get the contents. When I'd like to call the convert function, it showed me that it is undefined, so I wondering how should I the input file correctly. (geojsonContent is the content of geojson file, it has no problem)

    const converter = geojson2svg({
        width: 256,
        height: 256
    })
    
    const svgStrings = converter.convert(geojsonContent, {})
    console.log(svgStrings);
    
    opened by benebsiny 2
  • No possibility to convert Point as circle

    No possibility to convert Point as circle

    It seems there is bug and even pointAsCircle: true returns always path instead of circle.

    Problem is in instance.js in convertGeometry line 82 (return jsonToSvgElement(json,geom.type); doesnt call "opt" parameter, so in function jsonToSvgElement variable forcePath is always true.

    Now converted result looks like: <path cx="M611.5267122181064" cy="562.2759809701495 m-5" r="5" />

    Expected result: <circle cx="611.5267122181064" cy="562.2759809701495" r="5" />

    opened by franto 1
  • attributes of svg element are not correct

    attributes of svg element are not correct

    Attributes of an svg element can be given at two place, one in constructor and other in .convert function. If given at both places, attributes should be merged at .convert function and output svg string should contain attributes from both. There is issue only attributes from .convert function are being considered.

    Need to be resolved.

    opened by gagan-bansal 1
  • Added optional coordinateConversion method

    Added optional coordinateConversion method

    Example usage (for GlobalMercator, see https://gist.github.com/tadiraman/12f850ad5a6bdcdc59fb):

    var mercator = new GlobalMercator();
    var converter = geojson2svg(viewportSize,
       {coordinateConversion: mercator.LatLonToMeters});
    

    This can be used to generate SVG with correct projection to match web maps.

    opened by tadiraman 1
  • final step?

    final step?

    I'm trying to covert "Null Island.geo.json" to SVG using this tool. The conversion appears to go well but the svgString is a javascript array. [ 'M99.99268888888889,49.98556111111111 ...

    It is possible to get this output in XML/SVG, especially such that Inkscape can open it?

    opened by donpdonp 1
  • Typescript definition file

    Typescript definition file

    Fantastic library!

    Any chance you can add a Typescript definition file to the package? I can submit a PR for the following if it looks good to you:

    /***
     * https://github.com/gagan-bansal/geojson2svg
     */
    declare module 'geojson2svg' {
      import { GeoJSON } from 'geojson'
    
      export interface ScreenDims {
        width: number
        height: number
      }
    
      export interface Origin {
        x: number
        y: number
      }
    
      export interface Extent {
        left: number
        right: number
        bottom: number
        top: number
      }
    
      export interface StaticAttribute {
        type: 'static'
    
        /** The output attribute name */
        property: string
    
        /** The output attribute value */
        value: string
      }
    
      export interface DynamicAttribute {
        type: 'dynamic'
    
        /** The geojson source property name holding the output attribute value
         * ... also used as the output attribute name
         */
        property: string
    
        /** Override the output attribute name */
        key?: string
      }
    
      export interface ObjectAttributes {
        [key: string]: string
      }
    
      export interface Options {
        /** viewportSize is object containing width and height in pixels */
        viewportSize?: ScreenDims
    
        /** Coordinates should be in same projection as of geojson. Default maps extent are of Web Mercator projection (EPSG:3857). */
        mapExtent?: Extent
    
        /** Output format
         * 'svg' - svg element string is returned like '<path d="M0,0 20,10 106,40"/>'
         * 'path' - path 'd' value is returned 'M0,0 20,10 106,40' a linestring
         */
        output?: 'svg' | 'path'
    
        /** Fit ouput svg map to width or height. */
        fitTo?: 'width' | 'height'
    
        /** a number, precision of output svg coordinates. */
        precision?: number
    
        /** Should multigeojson be exploded to many svg elements or not. default is false. */
        explode?: boolean
    
        /** Attributes which are required to attach as SVG attributes from features can be passed here as list of path in feature or json object for static attributes */
        attributes?: (StaticAttribute | DynamicAttribute | ObjectAttributes)[] | ObjectAttributes
    
        /** Return geojson point objects as SVG circle elements. default is false. */
        pointAsCircle?: boolean
    
        /** radius of point svg element */
        r?: number
    
        /** function that will be called on every geojson conversion with output string as one input variable */
        callback?: (svgString: string) => void
      }
    
      export default class g2svg {
        public constructor(options?: Options)
        public convert(geojson: GeoJSON | any, options?: Options): string
      }
    }
    
    opened by shaunco 2
Owner
Gagan Bansal
Gagan Bansal
Geokit - is a command-line interface (CLI) tool written in javascript, that contains all the basic functionalities for measurements, conversions and operations of geojson files.

Geokit Geokit is a command-line interface (CLI) tool written in javascript, that contains all the basic functionalities for measurements, conversions

Development Seed 31 Nov 17, 2022
Tools for editing Shapefile, GeoJSON, TopoJSON and CSV files

Mapshaper Introduction Mapshaper is software for editing Shapefile, GeoJSON, TopoJSON, CSV and several other data formats, written in JavaScript. Maps

Matthew Bloch 3.2k Jan 2, 2023
modern parser & stringifier for WKT, EWKT, and GeoJSON

betterknown betterknown development is supported by ?? placemark.io I wrote wellknown, a WKT parser and stringifier, eons ago. It's still sort of popu

Placemark 32 Sep 3, 2022
Write or parse GeoJSON as YAML

geoyaml Write or parse GeoJSON as YAML. Like this: type: FeatureCollection features: - geometry: type: Point coordinates: - 37.9

Lou Huang 19 Dec 1, 2021
Reproject GeoJSON. Works Offline.

reproject-geojson Reproject GeoJSON features Works Offline Pure JavaScript Cross-Platform (NodeJS or Browser) install npm install reproject-geojson us

Daniel J. Dufour 8 Jul 22, 2022
A memory-efficient GeoJSON representation.

memory-geojson (experimental ?? ) A memory-efficient GeoJSON representation. This is not a new format. It's not meant to be serialized, and it doesn't

Tom MacWright 19 Nov 29, 2022
UNMAINTAINED Open source JavaScript renderer for Kartograph SVG maps

This project is not maintained anymore. Here are a few reasons why I stopped working on kartograph.js: there's no need to support non-SVG browsers any

null 1.5k Dec 11, 2022
Fast Map built for keys that are always fixed size uniformly distributed buffers.

turbo-hash-map Fast Map built for keys that are always fixed size uniformly distributed buffers. npm install turbo-hash-map Uses a prefix trie to map

Mathias Buus 39 Jun 20, 2022
An online tool to generate and visualize maps for irregular and/or gapped LED layouts, for use with FastLED, Pixelblaze and other libraries.

An online tool to generate and visualize maps for irregular and/or gapped LED layouts, for use with FastLED, Pixelblaze and other libraries.

Jason Coon 172 Dec 8, 2022
An open-source JavaScript library for world-class 3D globes and maps :earth_americas:

CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics

Cesium 9.7k Dec 26, 2022
An open-source JavaScript library for world-class 3D globes and maps :earth_americas:

CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics

Cesium 9.7k Jan 3, 2023
Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL

Mapbox GL JS is a JavaScript library for interactive, customizable vector maps on the web. It takes map styles that conform to the Mapbox Style Specif

Mapbox 9.4k Jan 7, 2023
:leaves: JavaScript library for mobile-friendly interactive maps

Leaflet is the leading open-source JavaScript library for mobile-friendly interactive maps. Weighing just about 39 KB of gzipped JS plus 4 KB of gzipp

Leaflet 36.5k Jan 1, 2023
the easiest way to use Google Maps

Important If you're developer, I'm moving gmaps.js to NPM, you can give your opinion and check the migration progress in Issue #404 gmaps.js - A Javas

Gustavo Leon 7.1k Dec 28, 2022
Polymaps is a free JavaScript library for making dynamic, interactive maps in modern web browsers.

Polymaps Polymaps is a free JavaScript library for making dynamic, interactive maps in modern web browsers. See http://polymaps.org for more details.

Urban Airship 1.6k Dec 23, 2022
the easiest way to use Google Maps

Important If you're developer, I'm moving gmaps.js to NPM, you can give your opinion and check the migration progress in Issue #404 gmaps.js - A Javas

Gustavo Leon 7.1k Apr 7, 2021
This is a collection of over two hundred code samples an growing for the Bing Maps V8 web control.

Bing Maps V8 Code Samples This is a collection of over a hundred code samples for the Bing Maps V8 web control. These samples have been collected from

Microsoft 130 Dec 8, 2022
This project contains the TypeScript definitions for the Bing Maps V8 Web Control.

Bing Maps V8 TypeScript Definitions These are the official TypeScript definitions for the Bing Maps V8 Web Control. These can be used to provide intel

Microsoft 35 Nov 23, 2022
React components for Leaflet maps

React Leaflet React components for Leaflet maps. Documentation Getting started API reference Changes See the CHANGELOG file. Contributing See the CONT

Paul Le Cam 4.4k Jan 3, 2023