Draw states in mapControl - winrt-xaml

I'm writing an application for windows Phone and I'm using a MapControl.
I'd like to be able to paint the US States in different colors.
For example, CA in Red, NV in blue, etc
I Thought about doing Shapes and Polilines, but I can't find the coordinates to use in the shapes to get the different States.
I also tried using the
var found = await MapLocationFinder.FindLocationsAsync("California", new Geopoint(new BasicGeoposition()));
but it doesn't work for finding States.

The best way is to download GeoJSON files from this public repository
https://github.com/johan/world.geo.json/tree/master/countries/USA
Parse the JSON and Create MapPolygon object and add it to map.
public async void RenderState() {
HttpClient client = new HttpClient();
HttpResponseMessage response=await client.GetAsync(new Uri("https://raw.githubusercontent.com/johan/world.geo.json/master/countries/USA/CO.geo.json"));
string json=response.Content.ToString();
JObject obj = JObject.Parse(json);
JObject poly = (JObject)obj["features"][0]["geometry"];
JArray coords = (JArray)poly["coordinates"][0];
MapPolygon polygon = new MapPolygon();
List<BasicGeoposition> points = new List<BasicGeoposition>();
foreach (JArray arr in coords) {
points.Add(new BasicGeoposition() { Latitude = (double)arr[1], Longitude = (double)arr[0] });
}
//Remove last point as it is a duplicate
if (points.Count > 1) {
points.RemoveAt(points.Count - 1);
}
polygon.Path = new Geopath(points);
polygon.StrokeColor = Colors.Red;
polygon.FillColor = Colors.Blue;
this.mMap.MapElements.Add(polygon);
}
This code will render the state of colarado

Related

Get polygon from Azure Maps Search

I'm trying to use Azure.Maps.Search to give me a polygon for a result. For example, if I search for "Birmingham" I would like a result for that municipality with a collection of geopoints defining the boundary.
Is this possible?
var credential = new AzureKeyCredential("............");
var client = new MapsSearchClient(credential);
Response<SearchAddressResult> searchResult = await client.SearchAddressAsync(
query: "Birmingham",
options: new SearchAddressOptions
{
ExtendedPostalCodesFor=new SearchIndex[] { SearchIndex.PointAddresses },
CountryFilter = new string[] { "GB" },
Top = 1,
EntityType = GeographicEntity.Municipality
});
Yes, this is possible. The search address API will contain a DataSources.Geometries.ID value in the results that is the ID of the unique boundary for that result. You can take this ID and pass it into the GetPolygonsAsync API in the Azure.Maps.Search Nuget package.
using Azure;
using Azure.Maps.Search;
using Azure.Maps.Search.Models;
namespace AzureMapsTest
{
internal class Program
{
private const string MapsApiKey = "...........";
static async Task Main(string[] args)
{
var credential = new AzureKeyCredential(MapsApiKey);
var client = new MapsSearchClient(credential);
SearchAddressOptions singleSearchResultOptions = new SearchAddressOptions { Top = 1 };
Response<SearchAddressResult> searchResult =
await client.SearchAddressAsync(
"Ealing, London, England",
singleSearchResultOptions);
Response<PolygonResult> polygons =
await client.GetPolygonsAsync(new string[] { searchResult.Value.Results[0].DataSources.Geometry.Id });
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(polygons.Value.Polygons));
}
}
}

Determine points that are under a sketchOverlay in a map

I have a map which has a GraphicsOverlay with various points. I have given the user the ability to select a subset of the points by drawing a polygon using the SketchEditor. How can I determine which points have been selected?
Here is a subset of the code to set up the map:
private GraphicsOverlay graphicsOverlayLow;
// Graphics overlay to host sketch graphics
private GraphicsOverlay _sketchOverlay;
var symbolLow = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Colors.Green, 10d);
graphicsOverlayLow = new GraphicsOverlay() { Renderer = new SimpleRenderer(symbolLow) };
foreach (var graphic in graphicListLow) // graphicListLow is a List of Points
graphicsOverlayLow.Graphics.Add(graphic);
MyMapView.GraphicsOverlays = new GraphicsOverlayCollection();
MyMapView.GraphicsOverlays.Add(graphicsOverlayLow);
_sketchOverlay = new GraphicsOverlay();
MyMapView.GraphicsOverlays.Add(_sketchOverlay);
I have two buttons, one for starting the drawing of the polygon and one to click when done (this follows the esri example for the SketchEditor). The code for starting is as follows:
private async void SelectButton_Click(object sender, RoutedEventArgs e)
{
try
{
// Let the user draw on the map view using the chosen sketch mode
SketchCreationMode creationMode = SketchCreationMode.Polygon;
Esri.ArcGISRuntime.Geometry.Geometry geometry = await MyMapView.SketchEditor.StartAsync(creationMode, true);
// Create and add a graphic from the geometry the user drew
Graphic graphic = CreateGraphic(geometry);
_sketchOverlay.Graphics.Add(graphic);
}
catch (TaskCanceledException)
{
// Ignore ... let the user cancel drawing
}
catch (Exception ex)
{
// Report exceptions
MessageBox.Show("Error drawing graphic shape: " + ex.Message);
}
}
private Graphic CreateGraphic(Esri.ArcGISRuntime.Geometry.Geometry geometry)
{
// Create a graphic to display the specified geometry
Symbol symbol = null;
switch (geometry.GeometryType)
{
// Symbolize with a fill symbol
case GeometryType.Envelope:
case GeometryType.Polygon:
{
symbol = new SimpleFillSymbol()
{
Color = Colors.Red,
Style = SimpleFillSymbolStyle.Solid,
};
break;
}
Here is the handler for the routine that is called when the user clicks the button signaling that they are done drawing the polygon. This is where I want to determine which points have been selected.
private void CompleteButton_Click(object sender, RoutedEventArgs e)
{
// Cancel execution of the sketch task if it is already active
if (MyMapView.SketchEditor.CancelCommand.CanExecute(null))
{
MyMapView.SketchEditor.CancelCommand.Execute(null);
}
}
Note that I am using the 100.4 SDK for WPF.
This can be accomplished by a spatial query. You will have to use the geometry returned by the sketch editor and use it to perform a spatial query on the layer(s) using geometry filter.
Esri.ArcGISRuntime.Geometry.Geometry geometry = await MyMapView.SketchEditor.StartAsync(creationMode, true);
var queryparameters = new QueryParameters()
{
Geometry = geometry,
SpatialRelationship = SpatialRelationship.Intersects
};
await layer.SelectFeaturesAsync(queryparameters, Esri.ArcGISRuntime.Mapping.SelectionMode.New);
You can use GeometryEngine.Intersects method to check when point graphics intersect, touch, cross the selection polygon.
https://community.esri.com/message/826699-re-determine-points-that-are-under-a-sketchoverlay-in-a-map?commentID=826699#comment-826699

Windows phone 8: How to send Object to an Event?

I'm developing an taxi caller app. And I used Bing map
This is my flow:
Get my position
Get 3 near taxis
When I tap 1 in 3 taxis, all in formation of taxis will sent to a new
Variable to used with another function.
This is my code
And how to send a obj from Foreach to taxiIcon_Tap?
Thanks and best regards!
//------ BEGIN get near Driver ------//
private async void GetNearDriver()
{
var uid = userData.content.uid;
var lat = pickupLat;
var lng = pickupLng;
var clvl = taxiType;
var input = string.Format("{{\"uid\":\"{0}\",\"lat\":{1},\"lng\":{2},\"cLvl\":\"{3}\"}}", uid, lat.ToString().Replace(',', '.'), lng.ToString().Replace(',', '.'), clvl);
var output = await GetJsonFromPOSTMethod.GetJsonString(ConstantVariable.tNetRiderGetNerDriverAddress, input);
var nearDriver = JsonConvert.DeserializeObject<RiderGetNearDriver>(output);
if (nearDriver.content.listDriverDTO.Count > 0)
{
foreach (var taxi in nearDriver.content.listDriverDTO)
{
ShowNearDrivers(taxi.lat, taxi.lng, taxi.cName);
}
}
}
//------ END get near Driver ------//
//------ BEGIN show and Design UI 3 taxi near current position ------//
private void ShowNearDrivers(double lat, double lng, string tName)
{
GeoCoordinate TaxiCoordinate = new GeoCoordinate(lat, lng);
//Create taxi icon on map
Image taxiIcon = new Image();
taxiIcon.Source = new BitmapImage(new Uri("/Images/Taxis/img_CarIcon.png", UriKind.Relative));
//Add a tapped event
taxiIcon.Tap += taxiIcon_Tap;
//Create Taxi Name
TextBlock taxiName = new TextBlock();
taxiName.HorizontalAlignment = HorizontalAlignment.Center;
taxiName.Text = tName;
taxiName.FontSize = 12;
taxiName.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)46, (byte)159, (byte)255)); //RBG color for #2e9fff
//Create Stack Panel to group icon, taxi name, ...
Rectangle taxiNameBackground = new Rectangle();
taxiNameBackground.Height = 18;
taxiNameBackground.Width = taxiName.ToString().Length + 20;
taxiNameBackground.RadiusX = 9;
taxiNameBackground.RadiusY = 7;
//taxiNameBackground.Stroke = new SolidColorBrush(Color.FromArgb(255, (byte)171, (byte)171, (byte)171)); //RBG color for #ababab
taxiNameBackground.Fill = new SolidColorBrush(Color.FromArgb(255, (byte)213, (byte)235, (byte)255)); //RBG color for #d5ebff
Grid taxiNameGrid = new Grid();
taxiNameGrid.Margin = new Thickness(0, 4, 0, 4); //Margin Top and Bottom 4px
taxiNameGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
taxiNameGrid.VerticalAlignment = System.Windows.VerticalAlignment.Center;
taxiNameGrid.Children.Add(taxiNameBackground);
taxiNameGrid.Children.Add(taxiName);
StackPanel taxiStackPanel = new StackPanel();
//taxiStackPanel.Margin = new Thickness(5, 0, 5, 0);
taxiStackPanel.Children.Add(taxiIcon);
taxiStackPanel.Children.Add(taxiNameGrid);
// Create a MapOverlay to contain the circle.
MapOverlay myTaxiOvelay = new MapOverlay();
//myTaxiOvelay.Content = myCircle;
myTaxiOvelay.Content = taxiStackPanel;
myTaxiOvelay.PositionOrigin = new Point(0.5, 0.5);
myTaxiOvelay.GeoCoordinate = TaxiCoordinate;
//Add to Map's Layer
riderMapLayer = new MapLayer();
riderMapLayer.Add(myTaxiOvelay);
map_RiderMap.Layers.Add(riderMapLayer);
}
//Tapped event
private void taxiIcon_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
//Hide Step 01
this.grv_Step01.Visibility = Visibility.Collapsed;
//Show Step 02
this.grv_Step02.Visibility = Visibility.Visible;
this.grv_Picker.Visibility = Visibility.Collapsed;
//Step 2 info
LoadStep2Info();
}
//------ END show and Design UI 3 taxi near current position ------//
You can use the Tag property to pass such miscellaneous objects around when using events which don't expose the ability to add an additional payload.
My understanding is that in the taxiIcon_Tap event you want to be able to access your own object that is related to whatever was tapped.
To do this set you object to the Tag property of the item being tapped.
i.e. If you want to pass the coordinates do:
taxiIcon.Tag = TaxiCoordinate;
(You could pass anything.)
Then, in the tapped event handler you can get at this object by casting from the sender to get the Tag and then casting that back to your type.
var coords = ((FrameworkElement)sender).Tag as GeoCoordinate;

AForge Hough Transform

Im trying to do an experiment on how to use the HoughTransformation class of AForge. Im using this class to try to count the number of circles on an image. But I always got this error message: Unsupported pixel format of the source image.
Here is my code:
private void CountCircles(Bitmap sourceImage)
{
HoughCircleTransformation circleTransform = new HoughCircleTransformation(15);
circleTransform.ProcessImage(sourceImage);
Bitmap houghCircleImage = circleTransform.ToBitmap();
int numCircles = circleTransform.CirclesCount;
MessageBox.Show("Number of circles found : "+numCircles.ToString());
}
HoughCircleTransformation expects a binary bitmap.
private void CountCircles(Bitmap sourceImage)
{
var filter = new FiltersSequence(new IFilter[]
{
Grayscale.CommonAlgorithms.BT709,
new Threshold(0x40)
});
var binaryImage = filter.Apply(bitmap);
HoughCircleTransformation circleTransform = new HoughCircleTransformation(15);
circleTransform.ProcessImage(binaryImage);
Bitmap houghCircleImage = circleTransform.ToBitmap();
int numCircles = circleTransform.CirclesCount;
MessageBox.Show("Number of circles found : "+numCircles.ToString());
}

Help on Removal of Dynamically Created sprites

import flash.display.Sprite;
import flash.net.URLLoader;
var index:int = 0;
var constY = 291;
var constW = 2;
var constH = 40;
hydrogenBtn.label = "Hydrogen";
heliumBtn.label = "Helium";
lithiumBtn.label = "Lithium";
hydrogenBtn.addEventListener (MouseEvent.CLICK, loadHydrogen);
heliumBtn.addEventListener (MouseEvent.CLICK, loadHelium);
lithiumBtn.addEventListener (MouseEvent.CLICK, loadLithium);
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
function loadHydrogen (event:Event):void {
myTextLoader.load(new URLRequest("hydrogen.txt"));
}
function loadHelium (event:Event):void {
myTextLoader.load(new URLRequest("helium.txt"));
}
function loadLithium (event:Event):void {
myTextLoader.load(new URLRequest("lithium.txt"));
}
var DataSet:Array = new Array();
var valueRead1:String;
var valueRead2:String;
function onLoaded(event:Event):void {
var rawData:String = event.target.data;
for(var i:int = 0; i<rawData.length; i++){
var commaIndex = rawData.search(",");
valueRead1 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead1);
commaIndex = rawData.search(",");
if(commaIndex == -1) {commaIndex = rawData.length+1;}
valueRead2 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead2);
}
generateMask_Emission(DataSet);
}
function generateMask_Emission(dataArray:Array):void{
var spriteName:String = "Mask"+index;
trace(spriteName);
this[spriteName] = new Sprite();
for (var i:int=0; i<dataArray.length; i+=2){
this[spriteName].graphics.beginFill(0x000000, dataArray[i+1]);
this[spriteName].graphics.drawRect(dataArray[i],constY,constW, constH);
this[spriteName].graphics.endFill();
}
addChild(this[spriteName]);
index++;
}
Hi, I am relatively new to flash and action script as well and I am having a problem getting the sprite to be removed after another is called. I am making emission spectrum's of 3 elements by dynamically generating the mask over a picture on the stage. Everything works perfectly fine with the code I have right now except the sprites stack on top of each other and I end up with bold lines all over my picture instead of a new set of lines each time i press a button.
I have tried using try/catch to remove the sprites and I have also rearranged the entire code from what is seen here to make 3 seperate entities (hoping I could remove them if they were seperate variables) instead of 2 functions that handle the whole process. I have tried everything to the extent of my knowledge (which is pretty minimal # this point) any suggestions?
Thanks ahead of time!
My AS3 knowledge is rather rudimentary right now but I think two things may help you.
You could use removeChild before recreating the Sprite. Alternatively, just reuse the Sprite.
Try to add this[spriteName].graphics.clear(); to reset the sprite and start redrawing.
function generateMask_Emission (dataArray : Array) : void {
var spriteName:String = "Mask"+index;
trace(spriteName);
// Don't recreate if sprite object already created
if (this[spriteName] == null)
{
this[spriteName] = new Sprite();
// Only need to add sprite to display object once
addChild(this[spriteName]);
}
for (var i:int= 0; i < dataArray.length; i+=2)
{
this[spriteName].graphics.clear();
this[spriteName].graphics.beginFill(0x000000, dataArray[i+1]);
this[spriteName].graphics.drawRect(dataArray[i],constY,constW, constH);
this[spriteName].graphics.endFill();
}
index++;
}
Just in case anyone was curious or having a similar problem. Extremely simple fix but here is what I did.
Also should mention that I don't think that the graphics.clear function actually fixed the problem (though I didn't have the sprite being cleared properly before), but I believe the problem lies in the beginning of the onloaded function where 3 of those variables used to be outside of the function.
import flash.display.Sprite;
import flash.net.URLLoader;
import flash.events.Event;
var constY = 291; //this value represets the Y value of the bottom of the background spectrum image
var constW = 2; //this value represents the width of every emission line
var constH = 40; //this value represents the height of every emission line
//Create Button Labels
hydrogenBtn.label = "Hydrogen";
heliumBtn.label = "Helium";
lithiumBtn.label = "Lithium";
//These listen for the buttons to be clicked to begin loading in the data
hydrogenBtn.addEventListener (MouseEvent.CLICK, loadHydrogen);
heliumBtn.addEventListener (MouseEvent.CLICK, loadHelium);
lithiumBtn.addEventListener (MouseEvent.CLICK, loadLithium);
var myTextLoader:URLLoader = new URLLoader();//the object to load in data from external files
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);//triggers the function when the file is loaded
var Mask:Sprite = new Sprite(); //This sprite will hold the information for the spectrum to be put on stage
function loadHydrogen (event:Event):void {
myTextLoader.load(new URLRequest("hydrogen.txt"));//starts loading Hydrogen emisson data
}
function loadHelium (event:Event):void {
myTextLoader.load(new URLRequest("helium.txt"));//starts loading Helium emission data
}
function loadLithium (event:Event):void {
myTextLoader.load(new URLRequest("lithium.txt"));//starts loading Lithium emission data
}
function onLoaded(event:Event):void {//the function that handles the data from the external file
var rawData:String = event.target.data; //create a new string and load in the data from the file
var DataSet:Array = new Array();//the array to load values in to
var valueRead1:String; //subset of array elements (n)
var valueRead2:String; //subset of array elements (n+1)
for(var i:int = 0; i<rawData.length; i++){ //loop through the string and cut up the data # commas
var commaIndex = rawData.search(",");
valueRead1 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead1);
commaIndex = rawData.search(",");
if(commaIndex == -1) {commaIndex = rawData.length+1;}
valueRead2 = rawData.substr(0,commaIndex);
rawData = rawData.substr(commaIndex+1, rawData.length+1);
DataSet.push(valueRead2);
}
generateMask_Emission(DataSet);//call the generateMaskEmission function on new data to fill emission lines
}
//This function loops through an array, setting alternating values as locations and alphas
function generateMask_Emission(dataArray:Array):void{
Mask.graphics.clear(); //Clears the Mask sprite for the next set of values
addChild(Mask); //Adds the blank sprite in order to clear the stage of old sprites
//This loop actually draws out how the sprite should look before it is added
for (var i:int=0; i<dataArray.length; i+=2){
Mask.graphics.beginFill(0x000000, dataArray[i+1]);
Mask.graphics.drawRect(dataArray[i],constY,constW, constH);
Mask.graphics.endFill();
}
addChild(Mask);// actually adds the mask we have created to the stage
}

Resources