private void ParseLabelLayerToList(List <GOParsedLayer> list, VectorTile vt, GOLabelsLayer layer) { string[] lyrs = tile.GetLabelsStrings().Split(','); // string kindKey = tile.GetPoisKindKey(); 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.labelsLayer = layer; pl.goFeatures = new List <GOFeature> (); for (int i = 0; i < featureCount; i++) { VectorTileFeature vtf = lyr.GetFeature(i); IDictionary properties = vtf.GetProperties(); List <List <LatLng> > geomWgs = vtf.GeometryAsWgs84((ulong)goTile.zoomLevel, (ulong)goTile.tileCoordinates.x, (ulong)goTile.tileCoordinates.y, 0); if (geomWgs.Count == 0 || geomWgs[0].Count <= 1) { continue; } GOFeature gf = new GOFeature(); gf.properties = properties; gf.goFeatureType = vtf.GOFeatureType(geomWgs); gf.labelsLayer = layer; gf.featureIndex = (Int64)i + vt.LayerNames().IndexOf(lyr.Name); gf.goTile = goTile; gf = tile.EditLabelData(gf); gf.goFeatureType = GOFeatureType.Label; gf.ConvertAttributes(); if (geomWgs.Count > 0) { gf.geometry = geomWgs[0]; gf.ConvertGeometries(); gf.preloadedLabelData = GOSegment.FindTheLongestStreightSegment(gf.convertedGeometry, 0); AddFatureToList(gf, pl.goFeatures); } } list.Add(pl); } } }
public IEnumerator Build(string name, GOFeature feature) { Profiler.BeginSample("[GOStreetName] text mesh settings"); TextMesh textMesh = gameObject.GetComponent <TextMesh>(); if (IsHebrew(name.ToCharArray()[0])) { textMesh.text = GOStreetName.Reverse(name); } else { textMesh.text = name; } GOStreetnamesSettings settings; switch (feature.goTile.mapType) { case GOMap.GOMapType.Nextzen: case GOMap.GOMapType.Mapbox: settings = feature.goTile.streetNames; break; default: settings = feature.labelsLayer.streetNames; break; } textMesh.color = settings.streetnameColor; //new Color (settings.streetnameColor.r,color.g,color.b); textMesh.anchor = TextAnchor.MiddleCenter; textMesh.alignment = TextAlignment.Center; textMesh.fontStyle = settings.fontStyle; textMesh.color = settings.streetnameColor; float minimumFontSize = settings.minFontSize; textMesh.font = settings.streetNameFont != null ? settings.streetNameFont : textMesh.font; textMesh.characterSize = settings.characterSize; textMesh.fontSize = settings.fontSize; MeshRenderer renderer = GetComponent <MeshRenderer>(); // renderer.shadowCastingMode = feature.layer.castShadows; textLenght = renderer.bounds.size.x; renderer.material = textMesh.font.material; Profiler.EndSample(); if (feature.convertedGeometry.Count > 1) { Profiler.BeginSample("[GOStreetName] find middle point"); GOSegment segment = feature.preloadedLabelData; //GOSegment.FindTheLongestStreightSegment (feature.convertedGeometry, 0); transform.localPosition = segment.findMiddlePoint(0.04f); //LineCenter (road._verts); transform.localScale = Vector3.one * 3; Profiler.EndSample(); Profiler.BeginSample("[GOStreetName] find correct size"); //Find correct size for (int i = textMesh.fontSize; i >= minimumFontSize - 1; i--) { textMesh.fontSize = i; float tl = renderer.bounds.size.x; if (segment.distance >= tl) { break; } if (i == minimumFontSize - 1) { GameObject.DestroyImmediate(this.gameObject); yield break; } } Profiler.EndSample(); var rotation = transform.eulerAngles; rotation.x = 90; Vector3 targetDir = segment.direction(); if (targetDir.Equals(Vector3.zero)) { rotation.y = 90; } else { Quaternion finalRotation = Quaternion.LookRotation(targetDir); rotation.y = finalRotation.eulerAngles.y + 90; rotation.y = (rotation.y % 360 + 360) % 360; if (rotation.y > 90 && rotation.y < 180) { rotation.y -= 180; } else if (rotation.y > 0 && rotation.y < 90) { rotation.y += 180; } } rot = rotation; transform.eulerAngles = rotation; } else if (feature.convertedGeometry.Count == 1) { transform.localPosition = feature.convertedGeometry[0]; transform.localScale = Vector3.one * 3; var rotation = transform.eulerAngles; rotation.x = 90; transform.eulerAngles = rotation; } if (settings.textShader != null) { Material m = renderer.sharedMaterial; m.shader = settings.textShader; m.color = textMesh.color; } yield return(null); }
public static int SortByDistance(GOSegment o1, GOSegment o2) { return(o1.distance.CompareTo(o2.distance)); }
public static GOSegment FindTheLongestStreightSegment(List <Vector3> line, float maxAngle) { Vector3 pointA = Vector3.zero; Vector3 pointB = Vector3.zero; float d = 0; float angle = 0; GOSegment spare = null; if (line.Count == 0) { } for (int i = 1; i < line.Count; i++) { if (i == 1) { pointA = line[0]; pointB = line[1]; d = Vector3.Distance(pointA, pointB); angle = AngleBetweenVector2XZ(pointA, pointB); continue; } Vector3 stepA = line[i - 1]; Vector3 stepB = line[i]; float stepD = Vector3.Distance(stepA, stepB); float stepAngle = AngleBetweenVector2XZ(stepA, stepB); float angleDiff = Mathf.Abs(stepAngle - angle); if (spare != null && Mathf.Abs(stepAngle - spare.angle) <= maxAngle) { stepD += spare.distance; stepA = spare.pointA; spare = null; } if (angleDiff > maxAngle) { //angle is too wide if (stepD > d) { //Reset segment pointA = stepA; pointB = stepB; d = stepD; angle = stepAngle; // Debug.Log ("Reset segment"); } else { //Save this segment for next step, just in case // Debug.Log ("Save segment"); GOSegment s = new GOSegment(); s.pointA = stepA; s.pointB = stepB; s.angle = stepAngle; s.distance = stepD; spare = s; } } else { //angle is ok, add the current segment pointB = stepB; d += stepD; // Debug.Log ("Add segment "+angle+ " " + stepAngle); } } GOSegment segment = new GOSegment(); segment.pointA = pointA; segment.pointB = pointB; segment.angle = angle; segment.distance = d; return(segment); }
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(); if (layer.layerType == GOLayer.GOLayerType.Roads) { gf.preloadedLabelData = GOSegment.FindTheLongestStreightSegment(gf.convertedGeometry, 0); } 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(); if (layer.layerType == GOLayer.GOLayerType.Roads) { gfm.preloadedLabelData = GOSegment.FindTheLongestStreightSegment(gfm.convertedGeometry, 0); } 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); } } }