{"id":13606542,"url":"https://github.com/esosedi/regions","last_synced_at":"2026-01-10T21:29:49.496Z","repository":{"id":26893448,"uuid":"30354726","full_name":"esosedi/regions","owner":"esosedi","description":"Module for Yandex, Google, Leaflet, D3 and other JS Maps with build in ability to display any region of the world. Or even an entire world. Based on OpenStreetMap and other sources","archived":false,"fork":false,"pushed_at":"2019-01-27T08:52:02.000Z","size":10245,"stargazers_count":97,"open_issues_count":10,"forks_count":17,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-31T01:31:53.214Z","etag":null,"topics":["administrative-divisions","borders","geojson","maps","topojson"],"latest_commit_sha":null,"homepage":"http://data.esosedi.org/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esosedi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-05T12:38:13.000Z","updated_at":"2024-12-07T19:33:00.000Z","dependencies_parsed_at":"2022-06-26T04:43:17.100Z","dependency_job_id":null,"html_url":"https://github.com/esosedi/regions","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosedi%2Fregions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosedi%2Fregions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosedi%2Fregions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esosedi%2Fregions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esosedi","download_url":"https://codeload.github.com/esosedi/regions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248281395,"owners_count":21077423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["administrative-divisions","borders","geojson","maps","topojson"],"created_at":"2024-08-01T19:01:10.047Z","updated_at":"2025-04-12T08:31:26.804Z","avatar_url":"https://github.com/esosedi.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# regions (code name osme)\nThe source of World's administrative divisions.\n\nThis is a module designed for: \n - [Yandex](https://tech.yandex.com/maps/), \n - [Google](https://developers.google.com/maps/), \n - [Leaflet](http://leafletjs.com/), \n - any other JS Maps to outline countries, counties and regions of the world.\n - being just a getJSON provider\n \n \nEach time you want to display borders - use the regions, Luke.\n \n[![NPM](https://nodei.co/npm/osme.png?downloads=true\u0026stars=true)](https://nodei.co/npm/osme/)\n\nRuns on top of information from [OpenStreetMap](http://openstreetmap.org), [Wikipedia](http://en.wikipedia.org), [GeoNames](http://geonames.org), [eSosedi](http://ru.esosedi.org) and some other sources.\n\nCreated for and used by [esosedi.org](http://ru.esosedi.org) project - one of largest cartographical site in the World.\n\n* This is neither lib nor API. This is a service.\n\n```js\n import osme from 'osme';\n```\nor \n```html\n \u003cscript src=\"https://unpkg.com/osme\"\u003e\u003c/script\u003e\n // use window.osme\n```\n![World](/_extra/images/world.png?raw=true) \n \n# API\nThere is only 2 primary commands:\n  * osme.geoJSON(addr, [options], [callback]):Promise - to get geoJSON for a region query\n  * osme.geocode(point, [options], [callback], [errorCallback]):Promise  - to find region by coordinates\n\nPlus we include build-in wrappers for Yandex Maps API, Google Maps API and Leaflet.\n  * osme.toGoogle(geoJson)\n  * osme.toYandex(geoJson)\n  * osme.toLeaflet(geoJson)\n      \n  All collections will have interface of .add .remove .setStyles .addEvent .removeEvent.\n  \n \n  Result it very simple - you can display any continent, country or state on a map.\n\n# As Service\n\nThe module consists in two parts, and this part is a client side. \nIt does not contain _any_ data, always striming it from the server side at [data.esosedi.org](http://data.esosedi.org). \nServer-side also implements online `navigator` via database to help you find proper place.\n\n* base service runs as 'http' service. Not https!, to https is provided by cloudflare and geolocated.org.\n\n# What I can load?\n   \n So, you can load: \n * `world` - all countries of the World.\n * geoScheme - 21 macro region of the World.\n _Africa, Americas, Asia, Europe, Oceania, Eastern Africa, Middle Africa, Northern Africa, Southern Africa, Western Africa, Cariebbean, Central America, Northern America, South America, Central Asia, Eastern Asia, South-Eastern Asia, Southern Asia, Western Asia, Eastern Europe, Northern Europe, Southern Europe, Western Europe, Australia and New Zealand, Melanesia, Micronesia, Polynesia._\n * iso3166-1 code. Country code. US, AU, DE and so on\n * iso3166-2 code. Region. US-WA, AU-NSW, RU-MOW and so on\n * special exports. bigMoscow, Moscow, SaintPetersburg, bigPiter and so on. Open a Pull Request if you need a special one.\n * `number` - as a OpenStreetMap RelationID. Ie - you can get contour of USA using `US` or `148838`, there is no difference.\n\n# Example\n* And check /examples folder!\n\n ```javascript\n import osmeRegions from 'osme';\n osme.geoJSON('FR').then( geojson =\u003e osme.toGoogle(geojson).add(map));\n ```\n\nA bit bigger one:\n```\n// ask for some region\nosme.geoJSON('US'/*addr*/, {lang: 'de'}, function (data) {\n    // data is pure GEOJSON\n    \n    // you can create some helpers\n    var yandexGeoObjectColletionWrapper = osme.toYandex(data);\n    // or\n    var googleDataWrapper = osme.toGoogle(data);\n    // or \n    var leafletDataWrapper = osme.toLeaflet(data);\n\n    // call .add to add data into the map\n    yandexGeoObjectColletionWrapper.add(map);\n    // call .remove to remove\n    googleDataWrapper.remove();\n    \n    // call setStyles to setup styles\n    leafletDataWrapper.setStyles(jsonFeatureIn =\u003e {\n       return styleOptions\n    });\n    \n    // And you also can control events.\n    *.addEvent(event,function(feature, apiType, apiObject, apiEvent){});\n    *.removeEvent();\n})\n\n// PS: OR you can use geoJSON as geoJSON. With out helpers\n    new L.geoJson(data).addTo(map);\n```\n\n# .geoJSON\n* osme.geoJSON(addr, options, callback)\nWhere:\n `addr` is OSM RelationId, [ISO3166-2](https://ru.wikipedia.org/wiki/ISO_3166-2) code(US/DE/GB or RU-MOS/US-TX etc, or [world's region name](https://en.wikipedia.org/wiki/Subregion)\n `options` is a object of { lang, quality, type, nocache, postFilter, recombine, scheme }. All are optional.\n \n        - lang - prefered language (en,de,ru)\n        - quality – set 0 to get geomentry for fullHD resolution. -1,0,+1,+2 for /4, x1, x4, x16 quality.\n        - type - null|'coast'. \n          - null to get `raw` `maritime` administrative borders, including terrotorial water.\n          - \"coast\", to cut off coast lines.\n        - nocache - turns of internal client-side cache\n        - postFilter, recombine, scheme - to be used only by advanced users. \n        \n\nIf you dont know relationId(`addr`) for region you need, you can:\n1. Traverse map database at [http://data.esosedi.org](http://data.esosedi.org).\n2. Use reverse geocode, via this lib, or via REST call - http://data.esosedi.org/geocode/v1?[lng=(ru|en)]\u0026point=x,y[\u0026seq=?][\u0026callback=?]\n3. Use [iso3166](https://github.com/esosedi/3166) library to get administrative divisions as a list.\n\n### type=coast\nType coast will return information you want - pretty borders. Very hi-detailed borders.\nHere is comparison between borders for Greece with and without maritime.\n[Greece](/_extra/images/maritime.png?raw=true)\nDifference - 154kb versus 251.\n\n### PS:\nInformation available for ~300k regions in 3 languages(en, de, ru) and some secret modes.\n\nThis module uses CORS to transport JSON via different hosts.\n\nYou can store geojson produced by this module, or cache packed json files from orinal data endpoint.\n\nJust change data-endpoint by executing `osme.setHost` command.\n\n* Remember: We have to provide copyright information, and you have to display it.\n\nData format is quite simple and compact. It is look like [topojson](https://github.com/mbostock/topojson), but more \"binary\" and contains data like schemes etc.\nAfter all you will get standard geoJSON. You can use it by your own risk.\n\nMore Examples:\n```\n\n// request Moscow\nosme.geoJSON('RU-MOW', {lang: 'ru'}, function (data) {\n    var collection = osme.toYandex(data, ymaps);\n    collection.add(geoMap);\n\n    geoMap.setBounds(collection.collection.getBounds(), {duration: 300});\n    \n    var strokeColors = [\n        '#000',\n        '#F0F',\n        '#00F',\n        '#0FF',\n    ];\n    var meta = data.metaData,\n        maxLevel = meta.levels[1] + 1;\n        \n    // colorize the collection    \n    collection.setStyles(function (object, yobject) {\n        var level = object.properties.level;\n        return ({\n            zIndex: level,\n            zIndexHover: level,\n            strokeWidth: Math.max(1, level == 2 ? 2 : (maxLevel - level)),\n            strokeColor: strokeColors[maxLevel - level] || '#000',\n            fillColor: '#FFE2',\n        });\n    });\n```\n![Moscow](/_extra/images/moscow.png?raw=true)\n\n# setStyles\n\nYou can do anything like country coloring (http://jsfiddle.net/9o9ak7fb/18/), or making \"old\" Moscow (http://jsfiddle.net/9o9ak7fb/17/).\nOSMe provide geo data, you provide logic.\n\n```\nvar countryColors={\n    'CA': \"F00\",\n    'IN': \"0F0\",\n    'US': \"00F\",\n    'RU': \"F0F\"\n};\n\nfunction setColors(collection, countryColors){\n     // You know this function\n     collection.setStyles(function (object) {\n        // get ISO counry code and color it\n        var iso = (object.properties.properties.iso3166 ||'').toUpperCase(),\n            color=countryColors[iso];\n        return ({\n            strokeWidth: 1,\n            strokeColor: color?'#000':\"666\",\n            fillColor: color || 'EEE',\n            visible: !!color\n        });\n    });\n}\n\n//...\nosme.geoJSON('world',{}).then(data =\u003e {\n  const collection = osme.toGoogle(data);\n  setColors(collection, countryColors);\n  collection.add(map);\n});\n```\n![Colour](/_extra/images/colorworld.png?raw=true)\n\n# addEvents\n\n```javascript\n  //any event - click, dblclick and so on.\n const event = collection.addEvent('dblclick', function (object, type, target, event) {\n     // object - object itself\n     // type – [eventName, provider('yandex','google')]\n     // target – Maps API`s feature (polygon) \n     // event – original event    \n    event.preventDefault();\n });\n collection.removeEvent(event);\n```\n\nAnd what about boundary dispute? Crimea, Kosovo, etc..\n\n# Magic of Recombine \n\nRecall strange parameter in options, field named `recombine`. This is not about boundaries, this is about recombination.\nIt is almost as language - en-US, or en-GB..\n\n* It can be string, and will be treated as key in scheme. Default equals to language.\n* Object with key - relation id, and value - javascript code.\n\nSee disputed-borders.html in /examples.\n\nRecombination allow you to create new geometry by combination of others.\n\nFor example something from internal cuisine - this code included in world.json file, and executed automatically\n```\n{\n    disputedBorders: {\n        ru: {\n            60199/*UA*/: 'return region.hasParent(60199) \u0026\u0026 region.osmId != 72639 \u0026\u0026 region.osmId != 1574364 \u0026\u0026 region.osmId!=421866;',\n            60189/*RU*/: 'return !region.hasParent(60189) \u0026\u0026 (region.osmId == 60189 || region.osmId == 72639 || region.osmId == 1574364)',\n        }\n    },\n    postFilter: 'return !region.hasParent(60199);', //remove UA*\n}\n```\nWhat this function do - it generates Ukraine without Crimea, or Russia with.\n - for #60199(Ukraine) - select all objects in 60199, but not Crimea and Kiev(internal shape)\n - for #60189(Russia) - selects RU, plus Crimea regions.\n - later - remove all regions of UA (exists in geoJSON file for this recombination) cos we require countries.\n\nYou can set options.recombine to a string ('ru' in this example) to select desired scheme, or set new scheme object. \n\n* By default recombine===lang.\n\nBy the same way you can join SJ to NO or GF to FR (one will understand).\n \nYou can create Merica by joining US to CA and MX or create EuroUnion.\n\nThe difference between recombination and just displaying everything you need - \nthe result of recombination is `borderless`. You will get not a pack of shapes, but BIG one.\n\nRecombination can be used to join any set of regions in one. This is usefull in many cases.\n\n```\n osme.geoJSON('349035', {lang: 'en'}, function (data, pureData) {\n    var coords=osme.recombine(pureData, { // yes, you can use pure data\n        filter: function (region) {\n            // somethere in Province of Barcelona (349035) and Barcelona(2417889) or adjacent\n            // remember - you have to discard #349035 or you got duplicate.\n            return region.hasParent(349035) \u0026\u0026 (region.hasBorderWith(2417889) || region.osmId == 2417889);\n        }\n    });\n    for(var j in coords.coordinates) {\n        var region = new ymaps.GeoObject({\n            geometry: {\n                type: 'Polygon',\n                fillRule: 'nonZero',\n                coordinates: osme.flipCoordinate([coords.coordinates[j]])\n            }\n        }, {\n            opacity: 0.8,\n            fillColor: 'FEE',\n            strokeColor: 'F00',\n            strokeWidth: 2,\n            pixelRendering: 'static',\n            draggable: true\n        });\n        geoMap.geoObjects.add(region);\n    }\n}\n```\nAnd you got mini Barcelona\n![Barcelona](/_extra/images/bars.png?raw=true)\n\nWhere is also exists options.scheme - yet another recombination function. It also sometimes exists in source geoJSON file.\nThe goal still simple - some regions lays on the top of other, and do not have adjacent borders - Kiev, for example, and Kiev province.\nScheme just adds \"hole\" to province.\n\n\nYou dont need to understand all of this - just use.\n\n# Remember\n* ! As any UGC project, may contain, contain and will `contain errors`, holes in data and mistakes.\n\n\nCheers, Kashey.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesosedi%2Fregions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesosedi%2Fregions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesosedi%2Fregions/lists"}