tangrams / tangram

WebGL map rendering engine for creative cartography
https://tangram.city
MIT License
2.22k stars 290 forks source link

Can scene load a object instead of yaml‘s URL? #593

Closed kengqiangxia closed 7 years ago

kengqiangxia commented 7 years ago

I know that Tangram.leafletLayer's scene parameter should load the URL of the scene yaml file.

I got GeoJSON instead of URL through program processing. I wanted to convert yaml into an JavaScript object, and then replace the yaml‘s URL parameter to GeoJSON. Tangram told me that "Scene.load() failed to load [object Object]".

I can't get the URL of GeoJSON, so I only can add Geojson as JSON mode, which makes it impossible for me to use yaml to load the URL of GeoJSON.

So, is there a way to load GeoJSON ? Thanks !

Wrong example:

var geojson = { "water": { "type": "FeatureCollection", "totalFeatures": "unknown", "features": [{ "type": "Feature", ...

var yaml = { sources: { mapzen: { type: 'GeoJSON', url: geojson, max_zoom: 16 } },

var layer = Tangram.leafletLayer({ scene: yaml, });

agenthunt commented 7 years ago

Yes something like this.

  1. Load everything in javascript Ex:
    
    const map = L.map(this.mapEl);
    const layer = Tangram.leafletLayer({
    scene: {
    cameras: { camera1: { type: "perspective" } },
    lights: {
      light1: {
        type: "directional",
        direction: [0, 1, "-.5"],
        diffuse: 0.3,
        ambient: 1
      }
    },
    sources: {
      mapzen: {
        type: "TopoJSON",
        url:
          "https://tile.mapzen.com/mapzen/vector/v1/all/{z}/{x}/{y}.topojson",
        url_params: { api_key: "mapzen-tDHBHDp" },
        max_zoom: 16
      }
    },
    layers: {
      earth: {
        data: { source: "mapzen" },
        draw: {
          polygons: {
            order: "function() { return feature.sort_rank; }",
            color: "#ff00ff"
          }
        }
      }
    },
    myline: {
      data: {
        source: "myline"
      },
      draw: {
        lines: {
          order: 100,
          color: [1, 0, 0, 1],
          width: "8px"
        }
      }
    }
    }
    });

layer.addTo(map); map.setView([40.70531887544228, -74.00976419448853], 15); layer.scene.subscribe({ load: () => { console.log("loaded"); layer.scene.setDataSource("myline", { type: "GeoJSON", data: { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "LineString", coordinates: [[-80, 35], [-122, 47]] }, properties: { prop0: "value0", prop1: 0.0 } } ] } }); }, view_complete: () => { console.log("scene view complete"); } });



You need to setDataSource to set geoJSON  instead of sources property https://mapzen.com/documentation/tangram/Javascript-API/#setdatasource_string_-name-_object_-config

2.    You can partially load from YAML file as well. Once the scene is loaded modify the scene.config object
bcamper commented 7 years ago

I believe that @agenthunt's response should answer your question.

There are two separate issues here:

  1. Loading the scene content (all the layers, textures, etc.) that are often stored as a YAML file. Tangram will accept a native JS object in place of the scene URL when creating or loading the Tangram map (as shown above).

  2. Loading a data source from native JS object (GeoJSON), instead of from a URL. As shown above, you can do this with scene.setDataSource(). If this is all you need to do, however, you could still load you original scene from an external YAML file. You can simply not define your data source in sources (it's OK for map layers to reference the data source even if it isn't defined yet, they will simply not display until the source is added). Then you can add your data source at run-time using scene.setDataSource().

kengqiangxia commented 7 years ago

@bcamper @agenthunt Thank you for giving me so much help! @agenthunt 's answers really solved my problem and I could load the map. But each tile's JSON is added to the map as many layers, and the map can be displayed when the first page is loaded. When I zoom this map, the page will crash, it may be due to too many layers.

Do you have a solution? Can I merge the JSON of multiple tiles into only one layer and add it to the map? Or, remove all the layers before I zoom the map, and then add layer to the map again?

I'm a beginner from China. I'm sorry to ask a lot of simple questions.

bcamper commented 7 years ago

Hmm... if you provide a single GeoJSON file, Tangram should split into tiles automatically for you.

Do you mean you are adding many different GeoJSON files, each as a separate layer? That should work but can be inefficient.

Could you provide a more complete example to explain what/how you are adding the data? Thanks.