diff --git a/src/Source/VectorTilesSource.js b/src/Source/VectorTilesSource.js index 77c1a0531b..979f42e829 100644 --- a/src/Source/VectorTilesSource.js +++ b/src/Source/VectorTilesSource.js @@ -144,7 +144,7 @@ class VectorTilesSource extends TMSSource { } return (Promise.resolve([this.url])); }).then((TMSUrlList) => { - this.url = new Set(TMSUrlList); + this.urls = Array.from(new Set(TMSUrlList)); }); } diff --git a/test/data/mapboxMulti.json b/test/data/mapboxMulti.json new file mode 100644 index 0000000000..c51f51804d --- /dev/null +++ b/test/data/mapboxMulti.json @@ -0,0 +1,438 @@ +{ + "attribution": "© Mapbox © OpenStreetMap Improve this map", + "bounds": [ + -180, + -85, + 180, + 85 + ], + "center": [ + 0, + 0, + 0 + ], + "created": 1527888859555, + "filesize": 0, + "fillzoom": 8, + "format": "pbf", + "id": "mapbox.mapbox-streets-v8", + "language_options": { + "ar": "Arabic", + "ca": "Catalan", + "cs": "Czech", + "da": "Danish", + "de": "German", + "el": "Greek", + "en": "English", + "es": "Spanish", + "fa": "Farsi", + "fi": "Finnish", + "fr": "French", + "he": "Hebrew", + "hu": "Hungarian", + "id": "Indonesian", + "it": "Italian", + "ja": "Japanese", + "ka": "Georgian", + "ko": "Korean", + "local": "Renderable local language", + "lv": "Latvian", + "ms": "Malay", + "nb": "Norwegian BokmÃ¥l", + "nl": "Dutch", + "no": "Norwegian", + "pl": "Polish", + "pt": "Portuguese", + "ro": "Romanian", + "ru": "Russian", + "sk": "Slovak", + "sl": "Slovenian", + "sr": "Serbian", + "sv": "Swedish", + "th": "Thai", + "tl": "Tagalog", + "tr": "Turkish", + "uk": "Ukrainian", + "vi": "Vietnamese", + "zh-Hans": "Simplified Chinese", + "zh-Hant": "Traditional Chinese" + }, + "mapbox_logo": true, + "maxzoom": 16, + "minzoom": 0, + "modified": 1692949181684, + "name": "Mapbox Streets v8", + "private": false, + "scheme": "xyz", + "tilejson": "2.2.0", + "tiles": [ + "https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v8/{z}/{x}/{y}.vector.pbf?access_token=pk.eyJ1IjoiZnRvcm9tYW5vZmYiLCJhIjoiY2xramhzM2xrMDVibjNpcGNvdGRlZWQ5YyJ9.NibhjJNVTxArsNSH4v_kIA", + "https://b.tiles.mapbox.com/v4/mapbox.mapbox-streets-v8/{z}/{x}/{y}.vector.pbf?access_token=pk.eyJ1IjoiZnRvcm9tYW5vZmYiLCJhIjoiY2xramhzM2xrMDVibjNpcGNvdGRlZWQ5YyJ9.NibhjJNVTxArsNSH4v_kIA" + ], + "vector_layers": [ + { + "description": "", + "fields": { + "class": "One of: aboriginal_lands, agriculture, airport, cemetery, commercial_area, facility, glacier, grass, hospital, industrial, park, parking, piste, pitch, residential, rock, sand, school, scrub, wood", + "type": "OSM tag, more specific than class" + }, + "id": "landuse", + "minzoom": 5, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "One of: river, canal, stream, stream_intermittent, ditch, drain", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "type": "One of: river, canal, stream, ditch, drain" + }, + "id": "waterway", + "minzoom": 7, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": {}, + "id": "water", + "minzoom": 0, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "ref": "Text. Identifier of the runway or taxiway", + "type": "One of: runway, taxiway, apron, helipad" + }, + "id": "aeroway", + "minzoom": 9, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "One of: cliff, crosswalk, entrance, fence, gate, hedge, land", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "type": "The value of either the 'barrier' or 'man_made' tag from OSM, or for cliffs either cliff or earth_bank." + }, + "id": "structure", + "minzoom": 13, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "extrude": "String. Whether building should be extruded when rendering in 3D. One of: 'true', 'false'", + "height": "Number. Height of building or part of building.", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "min_height": "Number. Height of bottom of building or part of building, if it does not start at ground level.", + "type": "In most cases, values will be that of the primary key from OpenStreetMap tags.", + "underground": "Text. Whether building is underground. One of: 'true', 'false'" + }, + "id": "building", + "minzoom": 12, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "One of: national_park, wetland, wetland_noveg", + "type": "OSM tag, more specific than class" + }, + "id": "landuse_overlay", + "minzoom": 5, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "bike_lane": "Text. Has a value if there is a bike lane that is part of the road itself. This is different from a separated cycle track, which will be shown as its own line. Possible values are 'right', 'left', 'both' (bike lane on right, left, or both sides of the street respectively), 'yes' (bike lane present but location not specified), 'no' (area was surveyed and confirmed to not have a bike lane), and null (presence of bike lane unknown).", + "class": "One of: 'motorway', 'motorway_link', 'trunk', 'primary', 'secondary', 'tertiary', 'trunk_link', 'primary_link', 'secondary_link', 'tertiary_link', 'street', 'street_limited', 'pedestrian', 'construction', 'track', 'service', 'ferry', 'path', 'golf', 'level_crossing', 'turning_circle', 'roundabout', 'mini_roundabout', 'turning_loop', 'traffic_signals'", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "lane_count": "Number. Number of lanes in the road", + "layer": "Number. Specifies z-ordering in the case of overlapping road segments. Common range is -5 to 5. Available from zoom level 13+.", + "len": "Number. Approximate length of the road segment in Mercator meters.", + "name": "Local name of the road", + "name_ar": "Arabic name of the road", + "name_de": "German name of the road", + "name_en": "English name of the road", + "name_es": "Spanish name of the road", + "name_fr": "French name of the road", + "name_it": "Italian name of the road", + "name_ja": "Japanese name of the road", + "name_ko": "Korean name of the road", + "name_pt": "Portuguese name of the road", + "name_ru": "Russian name of the road", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the road", + "name_zh-Hans": "Simplified Chinese name of the road", + "name_zh-Hant": "Traditional Chinese name of the road", + "oneway": "Text. Whether traffic on the road is one-way. One of: 'true', 'false'.", + "ref": "Text. Route number/code of the road.", + "reflen": "Number. How many characters long the ref tag is. Useful for shield styling.", + "shield": "Text. The shield style to use. See the vector tile documentation for a list of possible values.", + "shield_beta": "Text. The shield style to use if it doesn't exist in default shield values.", + "shield_text_color": "Text. The color of the text to use on the highway shield.", + "shield_text_color_beta": "Text. The color of the text to use on the beta highway shield.", + "structure": "Text. One of: 'none', 'bridge', 'tunnel', 'ford'. Available from zoom level 13+.", + "surface": "Whether the road is paved or not (if known). One of: 'paved', 'unpaved'", + "toll": "Whether a road is a toll road or not.", + "type": "In most cases, values will be that of the primary key from OpenStreetMap tags." + }, + "id": "road", + "minzoom": 3, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "admin_level": "Number, 0-2. The administrative level of the boundary", + "disputed": "Disputed boundaries are 'true', all others are 'false'.", + "iso_3166_1": "The ISO 3166-1 alpha-2 code(s) of the state(s) a boundary is part of. Format: 'AA' or 'AA-BB'", + "maritime": "Maritime boundaries are 'true', all others are 'false'.", + "worldview": "One of 'all', 'CN', 'IN', 'US'. Use for filtering boundaries to match different worldviews." + }, + "id": "admin", + "minzoom": 0, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "abbr": "Text. Local abbreviation of the place (available for type=state).", + "capital": "Admin level the city is a capital of, if any. One of: 2, 3, 4, 5, 6, null", + "class": "One of: country, state, settlement, or settlement_subdivision", + "filterrank": "Number, 0-5. Priority relative to nearby places. Useful for limiting label density.", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the place.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the road is in.", + "name": "Local name of the place", + "name_ar": "Arabic name of the place", + "name_de": "German name of the place", + "name_en": "English name of the place", + "name_es": "Spanish name of the place", + "name_fr": "French name of the place", + "name_it": "Italian name of the place", + "name_ja": "Japanese name of the place", + "name_ko": "Korean name of the place", + "name_pt": "Portuguese name of the place", + "name_ru": "Russian name of the place", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the place", + "name_zh-Hans": "Simplified Chinese name of the place", + "name_zh-Hant": "Traditional Chinese name of the place", + "symbolrank": "Number, 1-18. Useful for styling text & marker sizes.", + "text_anchor": "A hint for label placement at low zoom levels.", + "type": "One of: country, territory, sar, disputed_territory, state, city, town, village, hamlet, suburb, quarter, neighbourhood, island, islet, archipelago, residential, aboriginal_lands", + "worldview": "One of 'all', 'CN', 'IN', 'US'. Use for filtering boundaries to match different worldviews." + }, + "id": "place_label", + "minzoom": 0, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "One of: military, civil", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "maki": "One of: airport, heliport, rocket", + "name": "Local name of the airport", + "name_ar": "Arabic name of the airport", + "name_de": "German name of the airport", + "name_en": "English name of the airport", + "name_es": "Spanish name of the airport", + "name_fr": "French name of the airport", + "name_it": "Italian name of the airport", + "name_ja": "Japanese name of the airport", + "name_ko": "Korean name of the airport", + "name_pt": "Portuguese name of the airport", + "name_ru": "Russian name of the airport", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the airport", + "name_zh-Hans": "Simplified Chinese name of the airport", + "name_zh-Hant": "Traditional Chinese name of the airport", + "ref": "A 3-4 character IATA, FAA, ICAO, or other reference code", + "sizerank": "A scale-dependent feature size ranking from 0 (large) to 16 (small)", + "worldview": "One of 'all', 'CN', 'IN', 'US'. Use for filtering boundaries to match different worldviews." + }, + "id": "airport_label", + "minzoom": 8, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "filterrank": "Number, 0-5. Priority relative to nearby features. Useful for limiting label density.", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "maki": "One of: rail, rail-metro, rail-light, entrance, bus, bicycle-share, ferry", + "mode": "One of: rail, metro_rail, light_rail, tram, bus, monorail, funicular, bicycle, ferry, narrow_gauge, preserved, miniature", + "name": "Local name of the transit stop", + "name_ar": "Arabic name of the transit stop", + "name_de": "German name of the transit stop", + "name_en": "English name of the transit stop", + "name_es": "Spanish name of the transit stop", + "name_fr": "French name of the transit stop", + "name_it": "Italian name of the transit stop", + "name_ja": "Japanese name of the transit stop", + "name_ko": "Korean name of the transit stop", + "name_pt": "Portuguese name of the transit stop", + "name_ru": "Russian name of the transit stop", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the transit stop", + "name_zh-Hans": "Simplified Chinese name of the transit stop", + "name_zh-Hant": "Traditional Chinese name of the transit stop", + "network": "The network(s) that the station serves. Useful for icon styling.", + "network_beta": "One of: jp-shinkansen, jp-shinkansen.jp-jr, jp-shinkansen.tokyo-metro, jp-shinkansen.osaka-subway, jp-shinkansen.jp-jr.tokyo-metro, jp-shinkansen.jp-jr.osaka-subway, jp-jr, jp-jr.tokyo-metro, jp-jr.osaka-subway", + "stop_type": "One of: station, stop, entrance" + }, + "id": "transit_stop_label", + "minzoom": 5, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "One of: glacier, landform, water_feature, wetland, ocean, sea, river, water, reservoir, dock, canal, drain, ditch, stream, continent", + "elevation_ft": "Integer elevation in feet", + "elevation_m": "Integer elevation in meters", + "filterrank": "Number, 0-5. Priority relative to nearby features. Useful for limiting label density.", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "maki": "One of: 'mountain', 'volcano', 'waterfall'", + "name": "Local name of the natural feature", + "name_ar": "Arabic name of the natural feature", + "name_de": "German name of the natural feature", + "name_en": "English name of the natural feature", + "name_es": "Spanish name of the natural feature", + "name_fr": "French name of the natural feature", + "name_it": "Italian name of the natural feature", + "name_ja": "Japanese name of the natural feature", + "name_ko": "Korean name of the natural feature", + "name_pt": "Portuguese name of the natural feature", + "name_ru": "Russian name of the natural feature", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the natural feature", + "name_zh-Hans": "Simplified Chinese name of the natural feature", + "name_zh-Hant": "Traditional Chinese name of the natural feature", + "sizerank": "A scale-dependent feature size ranking from 0 (large) to 16 (small)", + "worldview": "One of 'all', 'CN', 'IN', 'US'. Use for filtering boundaries to match different worldviews." + }, + "id": "natural_label", + "minzoom": 0, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "brand": "String", + "category_en": "English category description of the POI", + "category_zh-Hans": "Simplified Chinese category description of the POI", + "class": "Text. Thematic groupings of POIs for filtering & styling.", + "filterrank": "Number, 0-5. Priority relative to nearby POIs. Useful for limiting label density.", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "maki": "The name of the Maki icon that should be used for the POI", + "maki_beta": "", + "maki_modifier": "", + "name": "Local name of the POI", + "name_ar": "Arabic name of the POI", + "name_de": "German name of the POI", + "name_en": "English name of the POI", + "name_es": "Spanish name of the POI", + "name_fr": "French name of the POI", + "name_it": "Italian name of the POI", + "name_ja": "Japanese name of the POI", + "name_ko": "Korean name of the POI", + "name_pt": "Portuguese name of the POI", + "name_ru": "Russian name of the POI", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the POI", + "name_zh-Hans": "Simplified Chinese name of the POI", + "name_zh-Hant": "Traditional Chinese name of the POI", + "sizerank": "A scale-dependent feature size ranking from 0 (large) to 16 (small)", + "type": "The original OSM tag value" + }, + "id": "poi_label", + "minzoom": 6, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "class": "The class of road the junction is on. Subset of classes in the road layer. One of: motorway, motorway_link, trunk, trunk_link, primary, secondary, tertiary, primary_link, secondary_link, tertiary_link, street, street_limited, construction, track, service, path, major_rail, minor_rail, service_rail.", + "filterrank": "Number, 0-5", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in.", + "maki_beta": "", + "name": "Local name of the motorway junction", + "name_ar": "Arabic name of the motorway junction", + "name_de": "German name of the motorway junction", + "name_en": "English name of the motorway junction", + "name_es": "Spanish name of the motorway junction", + "name_fr": "French name of the motorway junction", + "name_it": "Italian name of the motorway junction", + "name_ja": "Japanese name of the motorway junction", + "name_ko": "Korean name of the motorway junction", + "name_pt": "Portuguese name of the motorway junction", + "name_ru": "Russian name of the motorway junction", + "name_script": "Primary written script of the local name", + "name_vi": "Vietnamese name of the motorway junction", + "name_zh-Hans": "Simplified Chinese name of the motorway junction", + "name_zh-Hant": "Traditional Chinese name of the motorway junction", + "ref": "A short identifier", + "reflen": "The number of characters in the ref field.", + "type": "The type of road the junction is on. Subset of types in the road layer." + }, + "id": "motorway_junction", + "minzoom": 9, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + }, + { + "description": "", + "fields": { + "house_num": "House number", + "iso_3166_1": "Text. The ISO 3166-1 alpha-2 code of the country/territory the feature is in.", + "iso_3166_2": "Text. The ISO 3166-2 code of the state/province/region the feature is in." + }, + "id": "housenum_label", + "minzoom": 16, + "source": "mapbox.mapbox-streets-v8", + "source_name": "Mapbox Streets v8" + } + ], + "webpage": "https://studio.mapbox.com/tilesets/mapbox.mapbox-streets-v8", + "worldview_default": "US", + "worldview_options": { + "AR": "Argentina", + "CN": "China", + "IN": "India", + "JP": "Japan", + "MA": "Morocco", + "RS": "Serbia", + "RU": "Russia", + "TR": "Turkey", + "US": "United States" + } +} \ No newline at end of file diff --git a/test/unit/vectortiles.js b/test/unit/vectortiles.js index c473a10e81..5a55db0272 100644 --- a/test/unit/vectortiles.js +++ b/test/unit/vectortiles.js @@ -4,6 +4,7 @@ import VectorTileParser from 'Parser/VectorTileParser'; import VectorTilesSource from 'Source/VectorTilesSource'; import Extent from 'Core/Geographic/Extent'; import urlParser from 'Parser/MapBoxUrlParser'; +import { supportedFetchers } from 'Source/Source'; import Fetcher from 'Provider/Fetcher'; import sinon from 'sinon'; @@ -94,15 +95,23 @@ describe('Vector tiles', function () { }); describe('VectorTilesSource', function () { + let stubFetcherjson; let stub; before(function () { - stub = sinon.stub(Fetcher, 'json') + stubFetcherjson = sinon.stub(Fetcher, 'json') .callsFake((url) => { url = url.split('?')[0]; return Promise.resolve(JSON.parse(resources[url])); }); + const multipolygon = fs.readFileSync('test/data/pbf/multipolygon.pbf'); + const stubSupportedFetchers = new Map([ + ['application/x-protobuf;type=mapbox-vector', () => Promise.resolve(multipolygon)], + ]); + stub = sinon.stub(supportedFetchers, 'get') + .callsFake(format => stubSupportedFetchers.get(format)); }); after(function () { + stubFetcherjson.restore(); stub.restore(); }); @@ -121,9 +130,9 @@ describe('VectorTilesSource', function () { }, }); source.whenReady.then(() => { - assert.equal(source.url.size, 1); + assert.equal(source.urls.length, 1); // eslint-disable-next-line no-template-curly-in-string - assert.ok(source.url.has('http://server.geo/${z}/${x}/${y}.pbf')); + assert.ok(source.urls.includes('http://server.geo/${z}/${x}/${y}.pbf')); done(); }) .catch(done); @@ -148,7 +157,7 @@ describe('VectorTilesSource', function () { source.whenReady .then(() => { assert.equal(source.url, '.'); - assert.equal(source.urls.size, 1); + assert.equal(source.urls.length, 1); done(); }) .catch(done); @@ -194,7 +203,6 @@ describe('VectorTilesSource', function () { it('loads the style from a file', function _it(done) { const source = new VectorTilesSource({ style: 'test/data/vectortiles/style.json', - networkOptions: process.env.HTTPS_PROXY ? { agent: new HttpsProxyAgent(process.env.HTTPS_PROXY) } : {}, }); source.whenReady .then(() => { @@ -301,7 +309,7 @@ describe('VectorTilesSource', function () { }, source2: { type: 'vector', - tiles: ['http://server.geo2/{z}/{x}/{y}.pbf'], + tiles: ['http://server2.geo/{z}/{x}/{y}.pbf'], }, }, layers: [], @@ -309,11 +317,11 @@ describe('VectorTilesSource', function () { }); source.whenReady .then(() => { - assert.equal(source.url.size, 2); + assert.equal(source.urls.length, 2); // eslint-disable-next-line no-template-curly-in-string - assert.ok(source.url.has('http://server.geo/${z}/${x}/${y}.pbf')); + assert.ok(source.urls.includes('http://server.geo/${z}/${x}/${y}.pbf')); // eslint-disable-next-line no-template-curly-in-string - assert.ok(source.url.has('http://server.geo2/${z}/${x}/${y}.pbf')); + assert.ok(source.urls.includes('http://server2.geo/${z}/${x}/${y}.pbf')); done(); }) .catch(done); @@ -336,12 +344,55 @@ describe('VectorTilesSource', function () { }); source.whenReady .then(() => { - assert.equal(source.url.size, 1); + assert.equal(source.urls.length, 1); // eslint-disable-next-line no-template-curly-in-string - assert.ok(source.url.has('http://server.geo/${z}/${x}/${y}.pbf')); + assert.ok(source.urls.includes('http://server.geo/${z}/${x}/${y}.pbf')); done(); }) .catch(done); }); }); + + describe('loadData', function () { + it('with multisource', (done) => { + const source = new VectorTilesSource({ + style: { + sources: { + source1: { + type: 'vector', + tiles: ['http://server.geo/{z}/{x}/{y}.pbf'], + }, + source2: { + type: 'vector', + tiles: ['http://server2.geo/{z}/{x}/{y}.pbf'], + }, + }, + layers: [{ + id: 'geojson', + source: 'source1', + 'source-layer': 'geojson', + type: 'fill', + paint: { + 'fill-color': 'red', + }, + }], + }, + }); + + source.whenReady + .then(() => { + source.onLayerAdded({ out: { crs: 'EPSG:4326' } }); + const extent = new Extent('TMS', 1, 1, 1); + source.loadData(extent, { crs: 'EPSG:4326' }) + .then((featureCollection) => { + assert.equal(featureCollection.features[0].vertices.length, 20); + done(); + }) + .catch((err) => { + done(err); + }); + }) + .catch(done); + }); + }); });