//static int livingsign = 0; /// <summary> /// bildet rekursiv den Subdiv-Baum /// </summary> /// <param name="orgmap"></param> /// <param name="parentmap"></param> /// <param name="coordbits"></param> /// <param name="pointtypes"></param> /// <param name="linetypes"></param> /// <param name="areatypes"></param> /// <param name="level"></param> static void buildSubdivmapTree(DetailMap orgmap, DetailMap parentmap, int[] coordbits, IList <SortedSet <int> > pointtypes, IList <SortedSet <int> > linetypes, IList <SortedSet <int> > areatypes, int level = 0) { if (level >= coordbits.Length) { return; } split2Subdivmaps4Bits(orgmap, parentmap, coordbits[level], pointtypes[level], linetypes[level], areatypes[level]); //Console.Write("."); //if (++livingsign % 100 == 0) // Console.Write(livingsign); level++; for (int i = 0; i < parentmap.ChildMapCount; i++) { buildSubdivmapTree(orgmap, parentmap.GetChildMap(i), coordbits, pointtypes, linetypes, areatypes, level); } }
async protected override void OnAppearing() { base.OnAppearing(); var locator = CrossGeolocator.Current; var position = await locator.GetPositionAsync(); Latitude = position.Latitude; Longitude = position.Longitude; string GetAddress = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + Latitude.ToString() + "," + Longitude + "&key=" + api_key + "&language=th"; DetailMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(Latitude, Longitude), Distance.FromKilometers(1))); using (HttpResponseMessage response = await _client.GetAsync(GetAddress)) { if (response.StatusCode == System.Net.HttpStatusCode.OK) { using (HttpContent contents = response.Content) { string mycontent = await contents.ReadAsStringAsync(); JObject maps_details = JObject.Parse(mycontent); location_details = maps_details["results"][0]["formatted_address"].ToString(); } } else { await DisplayAlert("Error", "เกิดข้อผิดพลาดกรุณาลองใหม่", "OK"); } } var pin = new Pin { Position = new Position(Latitude, Longitude), Label = "ที่อยู่ปัจจุบัน", Address = location_details }; lb_Location_detail.Text = location_details; DetailMap.Pins.Add(pin); }
// from MKGMAP: /** * Split the area into portions that have the maximum size. There is a maximum limit to the size of a subdivision (16 bits or about 1.4 degrees at the most detailed zoom level). * * The size depends on the shift level. * * We are choosing a limit smaller than the real max to allow for uncertainty about what happens with features that extend beyond the box. * * If the area is already small enough then it will be returned unchanged. * * @param mapArea The area that needs to be split down. * @return An array of map areas. Each will be below the max size. * * * Die halbe Breite und Höhe einer Subdiv wird jeweils in 16 Bit gespeichert. MKGMAP verwendet sicherheitshalber sogar nur 15 Bit (0x7FFF). Die damit erreichbare * max. Breite und Höhe ist zusätzlich abhängig von der Bitanzahl für die Koordinaten * (SymbolicScaleAndBitsLevel.Bits(level) -> SubdivInfoBasic.Degree(rawunits, coordbits) -> GarminCoordinate.RawUnits2Degree(rawunits, coordbits)). * Schon daraus folgt, dass ein großes Subdiv bei einem größeren Maßstab/Zoom vermutlich in mehrere Subdiv's aufgeteilt werden muss. * * Weiterhin soll die Anzahl der Objekte in einer Subdiv nicht zu groß werden. * MKGMAP: Wenn * Punktanzahl > MAX_NUM_POINTS (0xFF) || * Linienanzahl > MAX_NUM_LINES (0xFF) || * (die Summe der geschätzten Datenbereichsgrößen für Punkte, Linien und Flächen) > MAX_RGN_SIZE (0xFFF8) || * (geschätzten Datenbereichsgrößen für erw. Punkte) > MAX_XT_POINTS_SIZE (0xFF00) || * (geschätzten Datenbereichsgrößen für erw. Linien) > MAX_XT_LINES_SIZE (0xFF00) || * (geschätzten Datenbereichsgrößen für erw. Flächen) > MAX_XT_SHAPES_SIZE (0xFF00) || * Subdiv > WANTED_MAX_AREA_SIZE (0x3FFF) * dann wir die Subdiv geteilt. Dabei wird je nach dem, welcher Wert größer ist, die Breite oder Höhe halbiert. * Linien und Flächen verteiltt MKGMAP nach der Lage ihrer Mittelpunkte. * * -> alle Objekte einer Karte für den akt. Maßstab codieren * Karte (mit den Objekten) rekursiv in Teilkarten aufteilen, wenn * die Breite und/oder Höhe zu groß ist || * Punktanzahl > MAX_NUM_POINTS (0xFF) || * Linienanzahl > MAX_NUM_LINES (0xFF) || * (die Summe der Datenbereichsgrößen für Punkte, Linien und Flächen) > MAX_RGN_SIZE (0xFFF8) || * (Datenbereichsgrößen für erw. Punkte) > MAX_XT_POINTS_SIZE (0xFF00) || * (Datenbereichsgrößen für erw. Linien) > MAX_XT_LINES_SIZE (0xFF00) || * (Datenbereichsgrößen für erw. Flächen) > MAX_XT_SHAPES_SIZE (0xFF00) || * Subdiv > WANTED_MAX_AREA_SIZE (0x3FFF) * * */ /// <summary> /// liefert die Liste der 'obersten' <see cref="DetailMap"/>'s, die jeweils mit den untergeordneten <see cref="DetailMap"/> verbunden sind und jeweils eine Subdiv repräsentieren /// </summary> /// <param name="orgmap"></param> /// <param name="coordbits">Bitanzahl je Ebene</param> /// <param name="pointtypes">erlaubte Punkttypen je Ebene</param> /// <param name="linetypes">erlaubte Linientypen je Ebene</param> /// <param name="areatypes">erlaubte Flächentypen je Ebene</param> /// <returns></returns> public static List <DetailMap> BuildSubdivmapMapTree(DetailMap orgmap, int[] coordbits, IList <SortedSet <int> > pointtypes, IList <SortedSet <int> > linetypes, IList <SortedSet <int> > areatypes) { //Console.WriteLine("Subdiv-Baum erzeugen ..."); //livingsign = 0; DetailMap firstlevelmap = orgmap.Copy(); buildSubdivmapTree(orgmap, firstlevelmap, coordbits, pointtypes, linetypes, areatypes); // Die Childs der firstlevelmap bilden die Subdivs der obersten Ebene. List <DetailMap> result = new List <DetailMap>(); for (int i = 0; i < firstlevelmap.ChildMapCount; i++) { DetailMap sd = firstlevelmap.GetChildMap(i); sd.ParentMap = null; result.Add(sd); } //Console.WriteLine(); return(result); }
/// <summary> /// erzeugt die Subdiv-Maps mit der gewünschten Bitanzahl mit den Objekten aus der Originalkarte im gewünschten Bereich und verknüpft sie mit der übergeordneten Map /// </summary> /// <param name="orgmap">Originalkarte mit ALLEN Objekten und max. Auflösung</param> /// <param name="parentmap"></param> /// <param name="coordbits">Bitanzahl</param> /// <param name="pointtypes">erlaubte Punkttypen</param> /// <param name="linetypes">erlaubte Linientypen</param> /// <param name="areatypes">erlaubte Flächentypen</param> static void split2Subdivmaps4Bits(DetailMap orgmap, DetailMap parentmap, int coordbits, SortedSet <int> pointtypes, SortedSet <int> linetypes, SortedSet <int> areatypes) { coordbits = Math.Max(10, Math.Min(coordbits, 24)); // eingrenzen 10 .. 24 DetailMap map4bits = PrepareMap(orgmap, coordbits, parentmap.DesiredBounds, pointtypes, linetypes, areatypes); List <DetailMap> subdivmaps = splitDetailMap(map4bits, coordbits, 0, 0); if (subdivmaps == null) { subdivmaps = new List <DetailMap>() { map4bits } } ; while (parentmap.ChildMapCount > 0) // ev. vorhandene Childs lösen { parentmap.GetChildMap(0).ParentMap = null; } foreach (var item in subdivmaps) { item.ParentMap = parentmap; } } // größere Werte können Probleme bei der Codierung der Delta-Werte ergeben //const int MAX_BOUND4LINE = 0x7FFF; // MKGMAP; etwa 0.703° bei 24 Bit //const int MAX_BOUND4AREA = 0xFFFF; // MKGMAP; etwa 1.406° bei 24 Bit const int MAX_BOUND4LINE = 0x7FFF; const int MAX_BOUND4AREA = 0x3FFF; /// <summary> /// kleinste Maximalgröße /// </summary> const int MIN_4MAX_BOUND = 0x7FFF; // MKGMAP 0x8000
public StationDetailPage(StationDetailViewModel model) { InitializeComponent(); BindingContext = viewModel = model; // Set map frame to the location of the selected station var position = new Position(Convert.ToDouble(viewModel.Latitude), Convert.ToDouble(viewModel.Longitude)); DetailMap.IsShowingUser = true; DetailMap.MoveToRegion( MapSpan .FromCenterAndRadius(position, Distance.FromMeters(500))); var pin = new Pin { Label = viewModel.Name, Position = position, Type = PinType.Place }; DetailMap.Pins.Add(pin); }
/// <summary> /// Test, ob die Karte (bei der vorgegebenen Bitanzahl) geteilt werden muss /// </summary> /// <param name="map"></param> /// <param name="coordbits"></param> /// <param name="width_divider">Teiler für die Breite</param> /// <param name="height_divider">Teiler für die Höhe</param> /// <returns></returns> static bool splitIsNeeded(DetailMap map, int coordbits, out int width_divider, out int height_divider) { bool isneeded = false; width_divider = 1; height_divider = 1; int halfwidth_rawunits = map.DesiredBounds.WidthRawUnits(coordbits) / 2; int halfheight_rawunits = map.DesiredBounds.HeightRawUnits(coordbits) / 2; if (halfwidth_rawunits > MAX_SUBDIV_HALFSIZE) { width_divider = halfwidth_rawunits / MAX_SUBDIV_HALFSIZE + 1; // nur ganzzahlige Teiler sinnvoll } if (halfheight_rawunits > MAX_SUBDIV_HALFSIZE) { height_divider = halfheight_rawunits / MAX_SUBDIV_HALFSIZE + 1; } if (width_divider > 1 || height_divider > 1) { isneeded = true; // Breite oder Höhe ist zu groß } else { if (map.PointCount(false) > MAX_NUM_POINTS) { isneeded = true; // zuviele Punkte } else if (map.LineCount(false) > MAX_NUM_LINES) { isneeded = true; // zuviele Linien } else { // Speicherplatzgrößen bestimmen StdFile_TRE.SubdivInfoBasic sdib = new StdFile_TRE.SubdivInfoBasic { Center = new MapUnitPoint(map.DesiredBounds.Left + map.DesiredBounds.Width / 2, map.DesiredBounds.Bottom + map.DesiredBounds.Height / 2) }; uint point_datalength = 0; uint extpoint_datalength = 0; foreach (DetailMap.Point point in map.PointList) { if (!point.IsExtendedType) { StdFile_RGN.RawPointData pd = new StdFile_RGN.RawPointData { Type = point.MainType, Subtype = point.SubType }; point_datalength += pd.DataLength; } else { StdFile_RGN.ExtRawPointData pd = new StdFile_RGN.ExtRawPointData { Type = point.MainType, Subtype = point.SubType, LabelOffsetInLBL = (uint)(string.IsNullOrEmpty(point.Label) ? 0 : 1) }; // ev. noch pd.ExtraBytes setzen extpoint_datalength += pd.DataLength; } } uint line_datalength = 0; uint extline_datalength = 0; foreach (DetailMap.Poly poly in map.LineList) { Debug.WriteLineIf(poly.PointCount < 2, string.Format("Fehler: Linie {0} hat nur {1} Punkt/e", poly, poly.PointCount)); if (poly.PointCount > 1) // min. 2 Punkte { if (!poly.IsExtendedType) { StdFile_RGN.RawPolyData polydat = poly.BuildRgnPolyData(sdib.Center, coordbits, false); polydat.LabelOffsetInLBL = (uint)(string.IsNullOrEmpty(poly.Label) ? 0 : 1); line_datalength += polydat.DataLength; } else { StdFile_RGN.ExtRawPolyData polydat = poly.BuildRgnExtPolyData(sdib.Center, coordbits); polydat.LabelOffsetInLBL = (uint)(string.IsNullOrEmpty(poly.Label) ? 0 : 1); extline_datalength += polydat.DataLength; } } } uint area_datalength = 0; uint extarea_datalength = 0; foreach (DetailMap.Poly poly in map.AreaList) { Debug.WriteLineIf(poly.PointCount < 3, string.Format("Fehler: Fläche {0} hat nur {1} Punkt/e", poly, poly.PointCount)); if (poly.PointCount > 2) // min. 3 Punkte { if (!poly.IsExtendedType) { StdFile_RGN.RawPolyData polydat = poly.BuildRgnPolyData(sdib.Center, coordbits, false); polydat.LabelOffsetInLBL = (uint)(string.IsNullOrEmpty(poly.Label) ? 0 : 1); area_datalength += polydat.DataLength; } else { StdFile_RGN.ExtRawPolyData polydat = poly.BuildRgnExtPolyData(sdib.Center, coordbits); polydat.LabelOffsetInLBL = (uint)(string.IsNullOrEmpty(poly.Label) ? 0 : 1); extarea_datalength += polydat.DataLength; } } } if (point_datalength + extpoint_datalength + line_datalength + extline_datalength + area_datalength + extarea_datalength > MAX_RGN_SIZE) { isneeded = true; // Datenbereich insgesamt zu groß } else if (extpoint_datalength > MAX_XT_POINTS_SIZE) { isneeded = true; // Datenbereich für erweiterte Punkte zu groß } else if (extline_datalength > MAX_XT_LINES_SIZE) { isneeded = true; // Datenbereich für erweiterte Linien zu groß } else if (extarea_datalength > MAX_XT_SHAPES_SIZE) { isneeded = true; // Datenbereich für erweiterte Flächen zu groß } } } if (isneeded) // Vierteilung { width_divider = 2; height_divider = 2; } return(isneeded); }
/* tmp bildet jetzt die Root des Teilkartenbaumes. * Jede "Ebene" des Baums ist für einen Zoomlevel zuständig. * Je stärker ge"zoomt" wird, je höher ist die Ebene. * * * * * * * * 2 \ | | | | | | \| | | | | | * * * * * * 1 \ | / | | / \|/ | |/ * * * 0 \ | / \ / / \/ / \/ * Originalkarte */ /// <summary> /// teilt eine einzelne (zu große) Karte in eine Liste von mindestens <see cref="width_divider"/> * <see cref="height_divider"/> Karten auf /// </summary> /// <param name="map"></param> /// <param name="coordbits"></param> /// <param name="width_divider">Teile in waagerechter Richtung</param> /// <param name="height_divider">Teile in senkrechter Richtung</param> /// <returns>null, wenn keine Aufteilung nötig ist</returns> static List <DetailMap> splitDetailMap(DetailMap map, int coordbits, int width_divider, int height_divider) { List <DetailMap> newmaps = new List <DetailMap>(); if (width_divider <= 1 && height_divider <= 1) { if (!splitIsNeeded(map, coordbits, out width_divider, out height_divider)) { return(null); } return(splitDetailMap(map, coordbits, width_divider, height_divider)); } else { Bound RawBound = map.DesiredBounds.AsRawUnitBound(coordbits); int halfwidth_rawunits = (RawBound.Width + 1) / 2; // der Wert ist auf keinen Fall zu klein, höchstens um +1 zu groß int halfheight_rawunits = (RawBound.Height + 1) / 2; int new_halfwidth_rawunits = halfwidth_rawunits / width_divider; int new_halfheight_rawunits = halfheight_rawunits / height_divider; if (new_halfwidth_rawunits * width_divider < halfwidth_rawunits) { new_halfwidth_rawunits++; // new_halfwidth_rawunits * width_divider deckt mit Sicherheit die Breite ab } if (new_halfheight_rawunits * height_divider < halfheight_rawunits) { new_halfheight_rawunits++; } for (int i = 0; i < width_divider; i++) { for (int j = 0; j < height_divider; j++) { int l = RawBound.Left + 2 * new_halfwidth_rawunits * i; int r = l + 2 * new_halfwidth_rawunits; int b = RawBound.Bottom + 2 * new_halfheight_rawunits * j; int t = b + 2 * new_halfheight_rawunits; newmaps.Add(new DetailMap(null, new Bound(l, r, b, t, coordbits))); } } } // ----- alle Teilkarten mit Objekten entsprechend ihrer Grenzen füllen foreach (DetailMap.Point pt in map.PointList) { int xcell = (int)((pt.Coordinates.Longitude - map.DesiredBounds.Left) / newmaps[0].DesiredBounds.Width); int ycell = (int)((pt.Coordinates.Latitude - map.DesiredBounds.Bottom) / newmaps[0].DesiredBounds.Height); newmaps[ycell * width_divider + xcell].PointList.Add(pt); } // Die Breite und Höhe der Karten ist für alle Karten gleich. int maxHeight = newmaps[0].DesiredBounds.Height; int maxWidth = newmaps[0].DesiredBounds.Width; //const int LARGE_OBJECT_DIM = 0x2000; //if (width_divider * height_divider == 1 || // maxWidth < LARGE_OBJECT_DIM || // maxHeight < LARGE_OBJECT_DIM) { // maxWidth = double.MaxValue; // maxHeight = double.MaxValue; //} foreach (DetailMap.Poly poly in map.LineList) { int xcell = (int)((poly.Bound.CenterX - map.DesiredBounds.Left) / maxWidth); int ycell = (int)((poly.Bound.CenterY - map.DesiredBounds.Bottom) / maxHeight); int idx = ycell * width_divider + xcell; if (!newmaps[idx].DesiredBounds.IsEnclosed(poly.Bound)) { if (!map.DesiredBounds.IsEnclosed(poly.Bound)) { throw new Exception(string.Format("Die Line ist zu groß für eine Subdiv bei {0} Bits: {1}", coordbits, poly.ToStringExt())); } newmaps.Add(new DetailMap(null, poly.Bound)); // zusätzliche "große" Karte für ein Einzelobjekt anhängen idx = newmaps.Count - 1; } newmaps[idx].LineList.Add(poly); } foreach (DetailMap.Poly poly in map.AreaList) { int xcell = (int)((poly.Bound.CenterX - map.DesiredBounds.Left) / maxWidth); int ycell = (int)((poly.Bound.CenterY - map.DesiredBounds.Bottom) / maxHeight); int idx = ycell * width_divider + xcell; if (!newmaps[idx].DesiredBounds.IsEnclosed(poly.Bound)) { if (!map.DesiredBounds.IsEnclosed(poly.Bound)) { throw new Exception(string.Format("Die Fläche ist zu groß für eine Subdiv bei {0} Bits: {1}", coordbits, poly.ToStringExt())); } newmaps.Add(new DetailMap(null, poly.Bound)); // zusätzliche "große" Karte anhängen idx = newmaps.Count - 1; } newmaps[idx].AreaList.Add(poly); } // ----- für jede neue Karte (rekursiv) testen, ob eine weitere Teilung nötig ist; dadurch kann sich die Liste noch verlängern for (int i = 0; i < newmaps.Count; i++) { if (splitIsNeeded(newmaps[i], coordbits, out width_divider, out height_divider)) { List <DetailMap> newmaps2 = splitDetailMap(newmaps[i], coordbits, width_divider, height_divider); newmaps.RemoveAt(i); newmaps.InsertRange(i, newmaps2); } } return(newmaps); }
const int MIN_4MAX_BOUND = 0x7FFF; // MKGMAP 0x8000 /// <summary> /// erzeugt eine Kopie der Originalkarte und teilt Objekte, die für die angegebene Bitanzahl zu groß sind auf /// <para>Dabei werden nur die gewünschten Objekttypen übernommen und es bleiben nur Objekte übrig, die eine Schnittmenge mit der gewünschten Umgrenzung haben.</para> /// </summary> /// <param name="orgmap"></param> /// <param name="coordbits"></param> /// <param name="destbound">nur Objekte, die diesen Bereich berühren</param> /// <param name="pointtypes">erlaubte Punkttypen</param> /// <param name="linetypes">erlaubte Linientypen</param> /// <param name="areatypes">erlaubte Flächentypen</param> /// <returns></returns> static DetailMap PrepareMap(DetailMap orgmap, int coordbits, Bound destbound, SortedSet <int> pointtypes, SortedSet <int> linetypes, SortedSet <int> areatypes) { DetailMap newmap = orgmap.Copy(destbound, false, pointtypes, linetypes, areatypes); int max_bound4line = Math.Min((1 << 24) - 1, Math.Max(MAX_BOUND4LINE << (24 - coordbits), MIN_4MAX_BOUND)); // MAX_BOUND4LINE << (24 - coordbits), aber eingegrenzt auf 0x8000 .. 0xFFFFFF int max_bound4area = Math.Min((1 << 24) - 1, Math.Max(MAX_BOUND4AREA << (24 - coordbits), MIN_4MAX_BOUND)); /* coordbits max_bound4line * Linie Fläche * Res maxSize maxSize * 24 0x007FFF 0x00FFFF * 23 0x00FFFF 0x01FFFF * 22 0x01FFFF 0x03FFFF * 21 0x03FFFF 0x07FFFF * 20 0x07FFFF 0x0FFFFF * 19 0x0FFFFF 0x1FFFFF * 18 0x1FFFFF 0x3FFFFF * 17 0x3FFFFF 0x7FFFFF * 16 0x7FFFFF 0xFFFFFF * 15 0xFFFFFF " * * Bei weniger als 15 Bit ist keine Aufteilung mehr nötig. */ // Linien und Flächen die zu groß sind, aufteilen List <DetailMap.Poly> lines = new List <DetailMap.Poly>(); foreach (var item in newmap.LineList) { lines.AddRange(MakeSafeLines(item, max_bound4line)); // 0.7° bei 24 Bit (je 1 Bit weniger verdoppeln) } newmap.LineList.Clear(); newmap.LineList.AddRange(lines); List <DetailMap.Poly> areas = new List <DetailMap.Poly>(); foreach (var item in newmap.AreaList) { areas.AddRange(MakeSafeAreas(item, max_bound4area)); } newmap.AreaList.Clear(); newmap.AreaList.AddRange(areas); // vollständig außerhalb des Zielbereiches liegende Objekte entfernen for (int i = 0; i < newmap.PointList.Count; i++) { if (!destbound.IsEnclosed(newmap.PointList[i].Coordinates)) // liegt außerhalb des Zielbereiches { newmap.PointList.RemoveAt(i--); } } for (int i = 0; i < newmap.LineList.Count; i++) { if (destbound.Intersection(newmap.LineList[i].Bound) == null) // liegt vollständig außerhalb des Zielbereiches { newmap.LineList.RemoveAt(i--); } } for (int i = 0; i < newmap.AreaList.Count; i++) { if (destbound.Intersection(newmap.AreaList[i].Bound) == null) // liegt vollständig außerhalb des Zielbereiches { newmap.AreaList.RemoveAt(i--); } } return(newmap); }
private void fillDetailMap(){ p_detailMap = new DetailMap(detailMapSize, details.Length); p_detailMap.heightMapSize = heightMapSize; DetailMapGenerator3 detailMapGenerator = new DetailMapGenerator3 (); detailMapGenerator.generate (p_detailMap, p_graphVoronoi); for (int i=0; i< p_detailMap.map.Count ; i++) p_terrain.terrainData.SetDetailLayer(0,0,i,p_detailMap.map[i]); }
public void generate(DetailMap detailMap, GraphVoronoi graphVoronoi ){ //each layer is drawn separately so if you have a lot of layers your draw calls will increase int detailMapSize = detailMap.mapSize; int numLayers = detailMap.numLayers; int heightMapSize = detailMap.heightMapSize; // float ratio = (float)m_terrainSize/(float)m_detailMapSize; //Random.seed = 0; for(int x = 0; x <detailMapSize; x ++) { for (int y = 0; y <detailMapSize; y ++) { for (int h=0; h<numLayers; h++) detailMap.setDetail(h,x,y,0); float ratio1 = (float)(heightMapSize-1)/(float)detailMapSize; Center.BiomeTypes biome = graphVoronoi.getNearestCenter((int)(x*ratio1),(int)(y*ratio1)).biome; int det = 10; if ((int)biome == 6) {det= 0;} if ((int)biome ==12) {det = 1;} if (( int)biome==8) {det=2;} //float unit = 1.0f / (m_detailMapSize - 1); //float normX = x * unit; //float normZ = z * unit; // Get the steepness value at the normalized coordinate. // float angle = terrain.terrainData.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. //float frac = angle / 90.0f; if(det<10 ) { /*float worldPosX = (x+(m_detailMapSize-1))*ratio; float worldPosZ = (z+(m_detailMapSize-1))*ratio; float noise = m_detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_detailFrq, 1.0f); if(noise > 0.0f) {*/ float rnd = Random.value; //Randomly select what layer to use if(rnd < 0.01f) detailMap.setDetail(0,x,y,1); else if(rnd < 0.75f) detailMap.setDetail(1,x,y,1); else detailMap.setDetail(2,x,y,1); } } } }
async protected override void OnAppearing() { animationView.IsVisible = true; base.OnAppearing(); var locator = CrossGeolocator.Current; var position = await locator.GetPositionAsync(); var Latitude = position.Latitude; var Longitude = position.Longitude; string GetAddress = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + Latitude.ToString() + "," + Longitude + "&key=" + api_key + "&language=th"; string sContentType = "application/json"; var jsonData = "{\"work_id\":\"" + work_id + "\"}"; var content = new StringContent(jsonData.ToString(), Encoding.UTF8, sContentType); using (HttpResponseMessage response = await _client.PostAsync(Url, content)) { if (response.StatusCode == System.Net.HttpStatusCode.OK) { using (HttpContent contents = response.Content) { string mycontent = await contents.ReadAsStringAsync(); List <Work_Detail> work_list = JsonConvert.DeserializeObject <List <Work_Detail> >(mycontent); var latlong = ""; for (var j = 0; j < work_list.Count; j++) { latlong += work_list[j].lat + "," + work_list[j].@long + "|"; } string GetAddress2 = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + Latitude + "," + Longitude + "&destinations=" + latlong + "&mode=driving&language=th-TH&sensor=false&key=AIzaSyA_v0m54p_3BHjOdaeteyY3VfvqoURhJ8Q&language=th"; using (HttpResponseMessage response2 = await _client.GetAsync(GetAddress2)) { if (response2.StatusCode == System.Net.HttpStatusCode.OK) { using (HttpContent contents2 = response2.Content) { string mycontent2 = await contents2.ReadAsStringAsync(); JObject maps_details = JObject.Parse(mycontent2); var map_d = maps_details["rows"][0]["elements"][0]["distance"]["text"].ToString(); var map_r1 = map_d.Replace("กม.", "กิโลเมตร"); var map_r2 = map_r1.Replace("ม.", "เมตร"); foreach (var x in work_list) { lb_owner_name.Text = x.job_owner_name.ToString(); lb_owner_tel.Text = x.tel + ""; lb_work_name.Text = x.work_name.ToString(); lb_work_desc.Text = x.work_desc.ToString(); lb_work_duration.Text = x.duration.ToString(); lb_labor_cost.Text = x.labor_cost.ToString() + " บาท"; lb_loc.Text = x.loc_name.ToString(); lb_distance.Text = map_r2; DetailMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(x.lat, x.@long), Distance.FromKilometers(1))); var pin = new Pin { Position = new Position(x.lat, x.@long), Label = "สถานที่ทำงาน", Address = x.loc_name }; DetailMap.Pins.Add(pin); DetailLoad.IsVisible = true; animationView.IsVisible = false; } } } } } } else { await DisplayAlert("เกิดข้อผิดพลาด", "Member id is null", "ตกลง"); } } }