private void ParseTilesetsToList(List <GOParsedLayer> list, VectorTile vt, GOTilesetLayer[] tilesets) { foreach (GOTilesetLayer tileSet in tilesets) { string kind = string.IsNullOrEmpty(tileSet.TilesetKindProperty)? tileSet.TilesetKindProperty : "kind"; VectorTileLayer lyr = vt.GetLayer(tileSet.TilesetName); if (lyr != null) { int featureCount = lyr.FeatureCount(); if (featureCount == 0) { continue; } GOParsedLayer pl = new GOParsedLayer(); pl.name = lyr.Name; pl.tilesetLayer = tileSet; pl.goFeatures = new List <GOFeature>(); for (int i = 0; i < featureCount; i++) { VectorTileFeature vtf = lyr.GetFeature(i); List <List <LatLng> > geomWgs = vtf.GeometryAsWgs84((ulong)goTile.zoomLevel, (ulong)goTile.tileCoordinates.x, (ulong)goTile.tileCoordinates.y, 0); GOFeature gf = new GOFeature(); gf.properties = vtf.GetProperties(); gf.attributes = GOFeature.PropertiesToAttributes(gf.properties); gf.goFeatureType = vtf.GOFeatureType(geomWgs); gf.tileSetKind = kind; gf.tilesetLayer = tileSet; gf.goTile = goTile; gf.featureIndex = (Int64)i; //gf.layerIndex = indexOfLayer; gf.featureCount = featureCount; //gf = tile.EditFeatureData(gf); gf.goTile = goTile; gf.ConvertAttributes(); if (gf.goFeatureType == GOFeatureType.Undefined) { continue; } string name = "Dataset " + gf.goFeatureType.ToString(); //Debug.Log(name); if (geomWgs.Count > 0 && (gf.goFeatureType == GOFeatureType.Point || gf.goFeatureType == GOFeatureType.MultiPoint)) //Probably needs a fix for multi points { //GOPOIKind kind = GOEnumUtils.PoiKindToEnum((string)properties[kindKey]); GOTilesetPOIRendering rendering = tileSet.TilesetPOIRenderingForKind(kind); if (rendering == null) { continue; } gf.geometry = geomWgs[0]; gf.tileSetPoiRendering = rendering; gf.name = name; gf.ConvertPOIGeometries(); AddFatureToList(gf, pl.goFeatures); } else if (geomWgs.Count > 0) { switch (gf.goFeatureType) { case GOFeatureType.Line: GOTilesetLINERendering lineRendering = tileSet.TilesetLINERenderingForKind(kind); if (lineRendering == null) { continue; } gf.geometry = geomWgs[0]; gf.ConvertGeometries(); gf.tileSetLineRendering = lineRendering; gf.name = name; gf.height = lineRendering.height; AddFatureToList(gf, pl.goFeatures); break; case GOFeatureType.Polygon: GOTilesetPOLYGONRendering polygonRendering = tileSet.TilesetPOLYGONRenderingForKind(kind); if (polygonRendering == null) { continue; } gf.geometry = geomWgs[0]; gf.ConvertGeometries(); gf.name = name; gf.tileSetPolygonRendering = polygonRendering; gf.height = polygonRendering.height; AddFatureToList(gf, pl.goFeatures); break; case GOFeatureType.MultiLine: lineRendering = tileSet.TilesetLINERenderingForKind(kind); if (lineRendering == null) { continue; } foreach (IList geometry in geomWgs) { float indexMulti = (((float)geomWgs.IndexOf((List <LatLng>)geometry) + 1) * (i + 1) / geomWgs.Count); GOFeature gfm = new GOFeature(gf); gf.name = name; gfm.geometry = geometry; gfm.ConvertGeometries(); gf.tileSetLineRendering = lineRendering; gf.height = lineRendering.height; AddFatureToList(gfm, pl.goFeatures); } break; case GOFeatureType.MultiPolygon: foreach (IList geometry in geomWgs) { polygonRendering = tileSet.TilesetPOLYGONRenderingForKind(kind); if (polygonRendering == null) { continue; } List <Vector3> convertedSubject = null; List <List <Vector3> > convertedClips = new List <List <Vector3> >(); for (int j = 0; j < geomWgs.Count; j++) { //Clip ascending IList p = geomWgs[j]; List <Vector3> convertedP = GOFeature.CoordsToVerts(p, false); if (GOFeature.IsClockwise(convertedP)) { convertedSubject = convertedP; } else { //Add clip convertedClips.Add(convertedP); } //Last one if (j == geomWgs.Count - 1 || (j < geomWgs.Count - 1 && GOFeature.IsGeoPolygonClockwise(geomWgs[j + 1]) && convertedSubject != null)) { GOFeature gfm = new GOFeature(gf); // gfm.index = (i +1)*j; gfm.convertedGeometry = convertedSubject; gfm.clips = convertedClips; gf.tileSetPolygonRendering = polygonRendering; gf.name = name; AddFatureToList(gfm, pl.goFeatures); convertedSubject = null; convertedClips = new List <List <Vector3> >(); } } } break; } } } list.Add(pl); } } }
private void ParseGOLayerToList(List <GOParsedLayer> list, VectorTile vt, GOLayer layer) { string[] lyrs = tile.GetLayersStrings(layer).Split(','); foreach (string l in lyrs) { VectorTileLayer lyr = vt.GetLayer(l); if (lyr != null) { int featureCount = lyr.FeatureCount(); if (featureCount == 0) { continue; } GOParsedLayer pl = new GOParsedLayer(); pl.name = lyr.Name; pl.goLayer = layer; pl.goFeatures = new List <GOFeature> (); int indexOfLayer = vt.LayerNames().IndexOf(lyr.Name); for (int i = 0; i < featureCount; i++) { VectorTileFeature vtf = lyr.GetFeature(i); List <List <LatLng> > geomWgs = vtf.GeometryAsWgs84((ulong)goTile.zoomLevel, (ulong)goTile.tileCoordinates.x, (ulong)goTile.tileCoordinates.y, 0); GOFeature gf; if (layer.layerType == GOLayer.GOLayerType.Roads) { gf = new GORoadFeature(); } else { gf = new GOFeature(); } gf.properties = vtf.GetProperties(); gf.attributes = GOFeature.PropertiesToAttributes(gf.properties); gf.goFeatureType = vtf.GOFeatureType(geomWgs); gf.layer = layer; gf.featureIndex = (Int64)i; gf.layerIndex = indexOfLayer; gf.featureCount = featureCount; gf = tile.EditFeatureData(gf); gf.goTile = goTile; // gf.setRenderingOptions (); gf.ConvertAttributes(); if (geomWgs.Count > 0) { switch (gf.goFeatureType) { case GOFeatureType.Line: gf.geometry = geomWgs [0]; gf.ConvertGeometries(); AddFatureToList(gf, pl.goFeatures); break; case GOFeatureType.Polygon: gf.geometry = geomWgs[0]; gf.ConvertGeometries(); AddFatureToList(gf, pl.goFeatures); break; case GOFeatureType.MultiLine: foreach (IList geometry in geomWgs) { float indexMulti = (((float)geomWgs.IndexOf((List <LatLng>)geometry) + 1) * (i + 1) / geomWgs.Count); GOFeature gfm; if (layer.layerType == GOLayer.GOLayerType.Roads) { gfm = new GORoadFeature((GORoadFeature)gf); } else { gfm = new GOFeature(gf); } // gfm.index = indexMulti; gfm.geometry = geometry; gfm.ConvertGeometries(); AddFatureToList(gfm, pl.goFeatures); } break; case GOFeatureType.MultiPolygon: foreach (IList geometry in geomWgs) { List <Vector3> convertedSubject = null; List <List <Vector3> > convertedClips = new List <List <Vector3> >(); for (int j = 0; j < geomWgs.Count; j++) //Clip ascending { IList p = geomWgs [j]; List <Vector3> convertedP = GOFeature.CoordsToVerts(p, layer.layerType == GOLayer.GOLayerType.Buildings); if (GOFeature.IsClockwise(convertedP)) { convertedSubject = convertedP; } else { //Add clip convertedClips.Add(convertedP); } //Last one if (j == geomWgs.Count - 1 || (j < geomWgs.Count - 1 && GOFeature.IsGeoPolygonClockwise(geomWgs [j + 1]) && convertedSubject != null)) { GOFeature gfm = new GOFeature(gf); // gfm.index = (i +1)*j; gfm.convertedGeometry = convertedSubject; gfm.clips = convertedClips; AddFatureToList(gfm, pl.goFeatures); convertedSubject = null; convertedClips = new List <List <Vector3> >(); } } } break; } } } if (goTile.combineFeatures) { pl = GOCombineFeatures.Combine(pl); } list.Add(pl); } } }
public IEnumerator BuildLayer(VectorTileLayer layerData, GOLayer layer, bool delayedLoad) { Profiler.BeginSample("[GoMap] [BuildLayer] game object"); GameObject parent = null; if (transform.Find(layer.name) == null) { parent = new GameObject(); parent.name = layer.name; parent.transform.parent = this.transform; parent.SetActive(!layer.startInactive); } else { parent = transform.Find(layer.name).gameObject; } Profiler.EndSample(); int featureCount = layerData.FeatureCount(); if (featureCount == 0) { yield break; } List <GOFeature> stack = new List <GOFeature> (); //Caching variables.. VectorTileFeature feature; List <List <LatLng> > geomWgs84; //= new List<List<LatLng>>(); GOFeature goFeature; Dictionary <string, object> properties = null; List <KeyValue> attributes = null; List <Vector3> convertedGeometry = null; for (int i = 0; i < featureCount; i++) { feature = layerData.GetFeature(i); properties = feature.GetProperties(); geomWgs84 = feature.GeometryAsWgs84((ulong)map.zoomLevel, (ulong)tileCoordinates.x, (ulong)tileCoordinates.y, 0); attributes = GOFeature.PropertiesToAttributes(properties); if (geomWgs84.Count > 0) { convertedGeometry = GOFeature.CoordsToVerts(geomWgs84[0], false); } //get the feature (here is the actual protobuf conversion) goFeature = ParseFeatureData(feature, properties, layer, -1, -1); //8-11mb if (layer.useOnly.Length > 0 && !layer.useOnly.Contains(goFeature.kind)) { continue; } if (layer.avoid.Length > 0 && layer.avoid.Contains(goFeature.kind)) { continue; } if (layer.layerType == GOLayer.GOLayerType.Roads) { GORoadFeature grf = (GORoadFeature)goFeature; if ((grf.isBridge && !layer.useBridges) || (grf.isTunnel && !layer.useTunnels) || (grf.isLink && !layer.useBridges)) { continue; } } GOFeatureType gotype = feature.GOFeatureType(geomWgs84); if (gotype == GOFeatureType.Undefined || feature.GeometryType == GeomType.POINT) { continue; } if (feature.GeometryType == GeomType.POLYGON && layer.layerType == GOLayer.GOLayerType.Roads) { continue; } Int64 index = vt.LayerNames().IndexOf(layerData.Name) + 1; GOFeature gf; Profiler.BeginSample("[GoMap] [BuildLayer] IF"); if (gotype == GOFeatureType.MultiLine || (gotype == GOFeatureType.Polygon && !layer.isPolygon)) { Profiler.BeginSample("[GoMap] [BuildLayer] multi line"); foreach (IList geometry in geomWgs84) { float indexMulti = ((float)geomWgs84.IndexOf((List <LatLng>)geometry) / geomWgs84.Count); gf = ParseFeatureData(feature, properties, layer, Convert.ToInt64(i) + indexMulti, index); gf.geometry = geometry; gf.layer = layer; gf.parent = parent; gf.properties = properties; gf.ConvertGeometries(); gf.attributes = attributes; gf.goFeatureType = GOFeatureType.MultiLine; stack.Add(gf); } Profiler.EndSample(); } else if (gotype == GOFeatureType.Line) { Profiler.BeginSample("[GoMap] [BuildLayer] line"); gf = ParseFeatureData(feature, properties, layer, Convert.ToInt64(i), index); gf.geometry = geomWgs84 [0]; gf.layer = layer; gf.parent = parent; gf.properties = properties; gf.convertedGeometry = convertedGeometry; gf.attributes = attributes; gf.index = (Int64)i + vt.LayerNames().IndexOf(layerData.Name); gf.goFeatureType = GOFeatureType.Line; if (geomWgs84.Count == 0) { continue; } stack.Add(gf); Profiler.EndSample(); } else if (gotype == GOFeatureType.Polygon) { Profiler.BeginSample("[GoMap] [BuildLayer] polygon"); gf = ParseFeatureData(feature, properties, layer, Convert.ToInt64(i), index); gf.geometry = geomWgs84 [0]; gf.layer = layer; gf.parent = parent; gf.properties = properties; gf.convertedGeometry = convertedGeometry; gf.attributes = attributes; gf.index = (Int64)i + vt.LayerNames().IndexOf(layerData.Name); gf.goFeatureType = GOFeatureType.Polygon; stack.Add(gf); Profiler.EndSample(); } else if (gotype == GOFeatureType.MultiPolygon) { Profiler.BeginSample("[GoMap] [BuildLayer] multi polygon"); // GameObject multi = new GameObject ("MultiPolygon"); // multi.transform.parent = parent.transform; IList subject = null; IList clips = new List <List <LatLng> >(); for (int j = 0; j < geomWgs84.Count; j++) //Clip ascending { IList p = geomWgs84 [j]; if (GOFeature.IsGeoPolygonClockwise(p)) { subject = p; } else { //Add clip clips.Add(p); } //Last one if (j == geomWgs84.Count - 1 || (j < geomWgs84.Count - 1 && GOFeature.IsGeoPolygonClockwise(geomWgs84 [j + 1]) && subject != null)) { gf = ParseFeatureData(feature, properties, layer, Convert.ToInt64(i), index); gf.geometry = subject; gf.clips = clips; gf.layer = layer; gf.parent = parent; gf.properties = properties; gf.ConvertGeometries(); gf.attributes = attributes; gf.index = (Int64)i + vt.LayerNames().IndexOf(layerData.Name); gf.goFeatureType = GOFeatureType.MultiPolygon; stack.Add(gf); subject = null; clips = new List <List <LatLng> >(); } } Profiler.EndSample(); } Profiler.EndSample(); } Profiler.BeginSample("[GoMap] [BuildLayer] merge roads"); IList iStack = (IList)stack; if (layer.layerType == GOLayer.GOLayerType.Roads) { iStack = GORoadFeature.MergeRoads(iStack); // Debug.Log ("Roads: "+stack.Count+" Merged: "+iStack.Count); } Profiler.EndSample(); int n = 25; for (int i = 0; i < iStack.Count; i += n) { for (int k = 0; k < n; k++) { if (i + k >= iStack.Count) { yield return(null); break; } GOFeature r = (GOFeature)iStack [i + k]; IEnumerator routine = r.BuildFeature(this, delayedLoad); if (routine != null) { if (Application.isPlaying) { StartCoroutine(routine); } else { GORoutine.start(routine, this); } } } yield return(null); } Resources.UnloadUnusedAssets(); yield return(null); }