POST
|
I know I'm being a word nazi here, but.... Toolbar depreciated? depreciated: decreased in value deprecated: has become superseded
... View more
04-04-2013
05:39 AM
|
0
|
0
|
227
|
POST
|
void queryTask_ExecuteCompleted(object sender, QueryEventArgs e) { attribWidget.featureDataGrid1.Map = this.MapControl; attribWidget.featureDataGrid1.ItemsSource = e.FeatureSet.Features; } But I have no success neither with DataGrid nor FeatureDataGrid ps: I don't want to make any previous selection on the map, so I don't need a graphic layer. I just want to display attributes on FeatureDataGrid Did you add a breakpoint in queryTask_ExecuteCompleted? is e.FeatureSet.Features returning results? If it's not returning anything then there's your problem. But if it is returning some features the problem might have to do with how the FeatureDataGrid is set up. For isntance, if you have AutoGenerateColumns=FALSE, then it might be unable to create the needed collumns and therefore not create any rows (just a guess). Also, A bit of advice: If it is just not working at all remove/change pieces of the example slowly and test after each one until it breaks so that way you can figure out where it's breaking and what you are doing to break it. Good luck!
... View more
04-04-2013
05:29 AM
|
0
|
0
|
102
|
POST
|
Hello and Welcome! You're going to have to be more detailed with your question if you want a more detailed response. For example, what are you trying to do exactly? Are you running into issues? Or is this more of a question just about how people have used it in the past?
... View more
04-04-2013
05:13 AM
|
0
|
0
|
273
|
POST
|
So it surely wasn't easy. In fact I never did get everything to work, but I did learn some things and perhaps others will be able to build upon this: My original reason for doing this original was that I didn't know what graphic I wanted to remove from being clustered until I saw what graphics were left over after clustering (by left-over I mean not clustered). I was able to cluster the graphics, but I wasn't able to do it properly. Clusters were far too close together and just sitting on top of eachother, or else they were just all gobbled together. But it also seemed that some graphics were just not getting grouped together. public override void ClusterGraphicsAsync(IEnumerable<Graphic> graphics, double resolution)
{
int incomingTotal = graphics.Count();
int total = 0;
//TODO run on seperate cancellable thread
//BackgroundWorkers or Tasks executed on the thread pool are possible options.
//if (bw.IsBusy != true)
//{
// bw.RunWorkerAsync();
//}
//else
//{
//}
GraphicCollection returnGraphics = new GraphicCollection();
//Group graphics into collections that will be turned into clusters
IEnumerable<GraphicCollection> graphicGroups = groupGraphics(graphics, resolution);
GraphicCollection gCollection;
for (int i = 0; i < graphicGroups.Count(); i++ )
{
gCollection = graphicGroups.ElementAt(i);
if (gCollection.Count > 2)
{
Utility.removeTextSymbols(ref gCollection); //need to remove TextSymbols or else they will be counted
MapPoint mp = getCenter(gCollection);
Graphic cluster = OnCreateGraphic2(gCollection, mp, gCollection.Count);
returnGraphics.Add(cluster);
total += gCollection.Count;
}
else //should just add one TextSymbol and one GraphicSymbol
{
foreach (Graphic g in gCollection)
{
returnGraphics.Add(g);
}
total += 1;
}
}
//raise ClusteringCompleted by invoking OnClusteringCompleted
OnClusteringCompleted(returnGraphics);
}
private IEnumerable<GraphicCollection> groupGraphics(IEnumerable<Graphic> graphics, double resolution)
{
Queue<Graphic> q = new Queue<Graphic>(graphics);
Collection<GraphicCollection> clusters = new Collection<GraphicCollection>();
int totalCount = 0;
double range = resolution * 50;
while (q.Count > 0)
{
Graphic g = q.Dequeue();
GraphicCollection gCollection = new GraphicCollection();
Envelope searchEnvelope = g.Geometry.Extent;
//expand the evelope to include the search resolution
searchEnvelope.XMax += (60*resolution);
searchEnvelope.YMax += (60*resolution);
searchEnvelope.XMin -= (60*resolution);
searchEnvelope.YMin -= (60*resolution);
gCollection.Add(g);
//iterate through q, finding all graphics within extent
if (q.Count > 0)
{
Graphic searchG = null;
Graphic firstSearchG = null;
Graphic prevSearchG = null;
//remove graphics from queue that are within searchEvelope
while (q.Count > 0 && (searchG == null || searchG != firstSearchG || prevSearchG == null))
{
prevSearchG = searchG;
searchG = q.Dequeue(); //new search graphic
if (firstSearchG == null)
{
firstSearchG = searchG;
}
//if (searchEnvelope.Intersects(searchG.Geometry.Extent) == true)
//if (envelopesIntersect(searchEnvelope, searchG.Geometry.Extent) == true)
if (withinRange(g, searchG, range) == true)
{
if (searchG.Symbol.GetType() == typeof(ESRI.ArcGIS.Client.FeatureService.Symbols.PictureMarkerSymbol))
{
gCollection.Insert(0,searchG);
}
else
{
gCollection.Add(searchG); //send textsymbol to end of colelction, so drawn last
}
totalCount++;
if (searchG == firstSearchG)
{
firstSearchG = null;
}
}
else
{
q.Enqueue(searchG);
}
}
}
clusters.Add(gCollection);
}
return clusters;
}
private bool withinRange(Graphic g1, Graphic g2, double range)
{
double a = g2.Geometry.Extent.YMax - g1.Geometry.Extent.YMax;
double b = g2.Geometry.Extent.XMax - g1.Geometry.Extent.XMax;
double c = Math.Sqrt(Math.Pow(a, 2) + Math.Pow(b, 2));
if (c <= range)
{
return true;
}
return false;
}
... View more
04-02-2013
01:04 PM
|
0
|
0
|
250
|
POST
|
If you check the area, if it's in the "wrong" direction I think it should be a negative area. But I wonder if this would still be true if the polygon had holes that were larger than the filled-space? Perhaps holes are just not factored at all?
... View more
04-01-2013
04:29 AM
|
0
|
0
|
174
|
POST
|
This is semi-related to this thread: How is ClusterGraphicsAsync suposed to be overridden? I have overridden OnCreateGraphic, but I'm a bit confused on overriding ClusterGraphicsAsync. From the API reference: The clustering algorithm is expected to run on a seperate cancellable thread to prevent blocking the UI. On completion, raise ClusteringCompleted by invoking OnClusteringCompleted. The event should not be raised if clustering was cancelled. I'm also guessing that ClusterGraphicsAsync calls OnCreateGraphic?, but in that case what does it do with the returned graphics? So my questions are: 1) How do I run on a seperate cancellable thread to prevent blocking the UI ? 2) How do raise ClusteringCompleted by invoking OnClusteringCompleted ? 3) How does CancelAsync factor into all of this? Much they also be overridden, if so how? 4a) Does ClusterGraphicsAsync call OnCreateGraphic? 4b) If so, what do you do with the returning graphics? 4c) If you create clusters from the "graphics" parameters based on the "resolution" parameter, is there a smart way of doing this, as this seems like it can be very complicated and easily could be O(n^2)? ANY thoughts are welcome
... View more
03-11-2013
06:30 AM
|
0
|
4
|
568
|
POST
|
The FieldAliases is a dictionary. I would suggest looking up what a dicitonary is for a better explanation, but essentially you pass it a key/string and it will return an value/string (or object if defined as so). Most likely you want to pass it the FieldName you want the alias of and it should return that alias.
... View more
03-11-2013
04:41 AM
|
0
|
0
|
202
|
POST
|
My situation: I have a bunch of Graphics that each have a Graphic label (uses TextSymbol as the symbol) associated with original graphics. When I do a cluster I want (problem 1) only the original Graphics to be clustered. I also want (problem 2) any singular graphics that are NOT clustered to retain their original graphic as well as their associated graphic/label. I am clustering via a flare clusterer, fyi. I have of course overridden OnCreateGraphic, which would be a fine place to do this. In fact I can just remove the labels from the cluster to be clustered and that takes care of problem 1. But now I need to solve problem 2: I can only return one graphic and since these labels are essentially in the same position as the original cluster I have always gotten at least 2 graphics (orignal graphic and label graphic) being passed to OnCreateGraphic as the cluster to be clustered. Since I can only pass back one graphic I have to choose which one to appear, the other one just doesnt show up. Is there a way to return more than one graphic? (unlikely?) So, with problem 2, I tried using the actual clusterer: I have run into some issues though. Simply setting the clusterer for the Layer, seems to behind the scenes call ClusterGraphicsAsync. The only way it seems to be to turn off clustering is to set the clusterer for the Layer to null. (this is how it is done in the examples I looked at). Also, it seems to be that ass soon as I add graphics to the layer they also get clustered. passing ClusterGraphicsAsync specific graphics seems to have no effect; it always clustered every graphic in the layer. I very much welcome any ideas on how to solve [my] problem 2. Bonus points if you can answer any of these questions: How do I cluster only SPECIFIC graphics on a layer? How do I turn off clustering without setting the clusterer to null? How do return more than one graphic or (*GASP* combine two graphics into one) from OnCreateGraphic?
... View more
03-08-2013
04:18 AM
|
0
|
0
|
497
|
POST
|
We decided to take a hammer to the situation and just create a class that builds a TextSymbol from Json... Here's the code that uses TexTSymbolBuilder
_textRenderer = (obj["drawingInfo"]["labelingInfo"]).ToString();
JArray array = JArray.Parse(_textRenderer);
JObject obj2 = JObject.Parse(array[0].ToString());
string tsym = array[0].ToString();
Graphic grtext;
foreach (Graphic graphic in featureSet.Features)
{
Dictionary<string,string> aliases = featureSet.FieldAliases;
graphic.Symbol = _resultRenderer.GetSymbol(graphic);
FrameworkElement maptip = getMapTip(graphic, aliases);
graphic.MapTip = maptip;
//text renderer
grtext = new Graphic();
grtext.Geometry = graphic.Geometry;
grtext.Symbol = TexTSymbolBuilder.BuildSymbolFromJson(tsym, graphic);
Here's the TexTSymbolBuilder code:
public static class TexTSymbolBuilder
{
public static TextSymbol BuildSymbolFromJson(string json,Graphic gr)
{
JObject obj2 = JObject.Parse(json);
string tsym = obj2["symbol"].ToString();
string lblExpression = obj2["labelExpression"].ToString().Replace("[", "").Replace("]", "");
string labelPlacement = obj2["labelPlacement"].ToString();
TextSymbol sym = new TextSymbol();
JObject objSym =( JObject)obj2["symbol"];
JObject Font = (JObject)objSym["font"];
sym.FontFamily = new FontFamily(Font["family"].ToString());
sym.FontSize = double.Parse(Font["size"].ToString());
sym.Foreground = ColorFromJson(objSym["color"].ToString());
Size labelSize = GetLabelWidth(gr.Attributes[lblExpression].ToString(),sym.FontSize);
switch (labelPlacement)
{
case "esriServerPointLabelPlacementCenterCenter":
sym.Text =gr.Attributes[lblExpression].ToString();
sym.OffsetX = labelSize.Width/2;//((gr.Attributes[lblExpression].ToString().Length * sym.FontSize) / 4);
sym.OffsetY = labelSize.Height/2;//(sym.FontSize / 2);
break;
}
return sym;
}
private static Size GetLabelWidth(string value,double fontsize)
{
Size sz = new Size();
TextBlock blk = new TextBlock();
blk.FontSize = fontsize;
blk.Text = value;
sz.Width = blk.ActualWidth;
sz.Height = blk.ActualHeight;
return sz;
}
private static Brush ColorFromJson(string p)
{
string clipped = p.Replace("[", "").Replace("]", "");
string[] vals = clipped.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
Color clr = Color.FromArgb(byte.Parse(vals[3]),byte.Parse(vals[0]),byte.Parse(vals[1]),byte.Parse(vals[2]));
Brush br = new SolidColorBrush(clr);
return br;
}
}
Hopefully this helps anyone what ran into the same issue
... View more
03-07-2013
06:43 AM
|
0
|
0
|
505
|
POST
|
"labellingInfo" contains not only the symbol but additionaly, "labelPlacement", "labelExpression",... To get the symbol, you could try: _textRenderer = (obj["drawingInfo"]["labelingInfo"]["symbol"]).ToString(); Not tested though. That code returns a ArgumentException: "Accessed JArray values with invalid key value: "symbol". Array position index expected." But I was able to get the symbol text via this code:
JObject obj2 = JObject.Parse(array[0].ToString());
string sym = obj2["symbol"].ToString();
But, still doing this just returns null from the FromJson method. Any ideas?
... View more
03-05-2013
03:32 AM
|
0
|
0
|
505
|
POST
|
I am trying to grab the labeling info from a DynamicMapServiceLayer and add that to my featurelayer. Currently, a query is sent to the DynamicMapService and returns with the requested FeatureSet. FYI, part of the reason we are doing it this way is so that we can add customized flare clusters. At this point, we'd like to grab the labeling info and add to the map.
JObject obj = JObject.Parse(strConfig);
string strRenderer = (obj["drawingInfo"]["renderer"]).ToString();
_resultRenderer = Renderer.FromJson(strRenderer);
_textRenderer = (obj["drawingInfo"]["labelingInfo"]).ToString();
TextSymbol textSymbol = (TextSymbol)TextSymbol.FromJson(_textRenderer);
Note: _resultRenderer returns a valid object, but textSymbol ALWAYS returns null. If I don't put it in the correct format the .FromJson method will complain, so it doesn't appear to be a formatting issue. Here is the string "_textRenderer": "[\r\n {\r\n \"labelPlacement\": \"esriServerPointLabelPlacementCenterCenter\",\r\n \"labelExpression\": \"[NOTIFICATIONTYPE]\",\r\n \"useCodedValues\": true,\r\n \"symbol\": {\r\n \"type\": \"esriTS\",\r\n \"color\": [\r\n 255,\r\n 255,\r\n 255,\r\n 255\r\n ],\r\n \"backgroundColor\": null,\r\n \"borderLineColor\": null,\r\n \"verticalAlignment\": \"bottom\",\r\n \"horizontalAlignment\": \"center\",\r\n \"rightToLeft\": false,\r\n \"angle\": 0,\r\n \"xoffset\": 0,\r\n \"yoffset\": 0,\r\n \"font\": {\r\n \"family\": \"Arial\",\r\n \"size\": 6,\r\n \"style\": \"normal\",\r\n \"weight\": \"normal\",\r\n \"decoration\": \"none\"\r\n }\r\n },\r\n \"minScale\": 0,\r\n \"maxScale\": 0\r\n }\r\n]";
... View more
03-04-2013
11:23 AM
|
0
|
5
|
895
|
POST
|
After doing some more research today was able to find this method and documentation in QueryTask: ExecuteCountAsync Executes a query against an ArcGIS Server map layer and counts the results. If the query is successful, the QueryTask.ExecuteCountCompleted event is raised with the result.
... View more
02-12-2013
05:02 AM
|
0
|
0
|
176
|
POST
|
I would like to display to the user the number of features/graphics that are displayed out of how many would be displayed if all of the graphics were returned. Currently my service is set to max out at returning 1000 graphics, but our DB holds ~85,0000. When a user submits a query that has 3235 results, I'd like to be able to display "Only showing 1000 of 3235" results or similar.
... View more
02-11-2013
01:07 PM
|
0
|
1
|
603
|
POST
|
I wasn't abel to get the data binding to work, but because of the post I was able to realize I could just create the maptips for each individual graphic, though I wonder if by doing that it's less effecient... oh well. Here's what I did: I created a function to create the mapTip here private FrameworkElement getMapTip(Graphic graphic) { Grid grid = new Grid(); grid.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255)); grid.Margin = new Thickness(2); //create outer stack panel StackPanel outerStackPanel = new StackPanel(); outerStackPanel.Margin = new Thickness(5); //add border to grid Border border = new Border(); border.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 0, 255, 0)); border.CornerRadius = new CornerRadius(2); border.Child = outerStackPanel; //put border around outer stack panel foreach (string attribute in _mapTipAttributes) { TextBlock txtBlock = new TextBlock(); txtBlock.Text = attribute + ": " + graphic.Attributes[attribute]; outerStackPanel.Children.Add(txtBlock); } grid.Children.Add(border); return grid; } and I call it where I create my graphics: void queryTask_ExecuteCompleted(object sender, QueryEventArgs args) { FeatureSet featureSet = args.FeatureSet; if (featureSet == null || featureSet.Features.Count < 1) { MessageBox.Show("No features returned from query"); return; } GraphicsLayer graphicsLayer = _map.Layers["NotifLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); foreach (Graphic graphic in featureSet.Features) { graphic.Symbol = LayoutRoot.Resources["YellowMarkerSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol; graphic.MapTip = getMapTip(graphic); graphicsLayer.Graphics.Add(graphic); } }
... View more
02-11-2013
01:00 PM
|
0
|
0
|
213
|
POST
|
Likely there are lots of possibilities. One option is to first define your maptip as an ItemsControl allowing to display a list of attributes. Something like this (for example with a datagrid): <esri:FeatureLayer.MapTip>
<sdk:DataGrid ItemsSource="{Binding}" HeadersVisibility="None"/>
</esri:FeatureLayer.MapTip> Then you could develop a value converter taking an attributes dictionary as input and returning a dictionary with the attributes you want to display (how you filter the attributes is depending on your application). Then you can use this converter in XAML: <esri:FeatureLayer.MapTip>
<sdk:DataGrid ItemsSource="{Binding Converter={StaticResource myDictionaryFilterConverter}}" HeadersVisibility="None"/>
</esri:FeatureLayer.MapTip> Hope this helps. Where do I put that XAML though? My graphics layer is defined in code? Will I have to move it to XAML? Or can I define the binding in the code behind?
... View more
02-11-2013
03:40 AM
|
0
|
0
|
213
|
Title | Kudos | Posted |
---|---|---|
1 | 04-16-2015 07:43 AM |
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:24 AM
|