Hi,
The sample "FindTheFeatureAUserClickedOn" works only with polygon ...How to get it work with point & lines
Patrick.
Hi,
The sample "FindTheFeatureAUserClickedOn" works only with polygon ...How to get it work with point & lines
Patrick.
Patrick,
I think this depends on how Spatial Query works, in our HowDoISamples\FindThe FeatureAUserClickedOn, it use the containing Spatial Query which cannot apply to Line &Point type data.
If you want, you can play with other kinds of Spatial Query to see it is suitable for you, following is the code you can take a reference.
FeatureLayer pointLayer = winformMap1.FindFeatureLayer("PointLayer");
pointLayer.Open();
Collection<Feature> selectedFeatures = pointLayer.QueryTools.GetFeaturesNearestTo(e.WorldLocation, winformMap1.MapUnit, 1, ReturningColumnsType.AllColumns);
pointLayer.Close();
if (selectedFeatures.Count > 0)
{
string text = "Found";
MessageBox.Show(text, "Note", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0);
}
Any more questions just let me know.
Yale
Thank you, Yale.
This does not do what I’m expecting. what I’m expecting is the way API 2.0 “theMap.Mode = ModeType.SelectFeatures;” was working.
Basicaly what you’re proposing is to get features distant from 1m from the user click. This depends on the scale.
What I need is to get features distant from 10 pixel from the user click.
I’ll adapt this to take care of the scale, but I believe you should add this to your samples … it’s a very simple & commun behaviour.
Thanks,
Patrick.
Yale,
additionnaly, GetFeaturesNearestTo does not seems to work. It returns a feature that is not the closest one to the user click.
here is my code, please help:
lp.Open();
selectedFeatures = lp.QueryTools.GetFeaturesNearestTo(e.WorldLocation,
theMap.MapUnit,
1,
ReturningColumnsType.AllColumns);
lp.Close();
if user clicks more than once, then it appears that every features are returned randomly; even some distant of many kilometers.
Patrick.
Posted By Patrick on 06-22-2009 01:30 AM
Thank you, Yale.
This does not do what I’m expecting. what I’m expecting is the way API 2.0 “theMap.Mode = ModeType.SelectFeatures;” was working.
Basicaly what you’re proposing is to get features distant from 1m from the user click. This depends on the scale.
What I need is to get features distant from 10 pixel from the user click.
I’ll adapt this to take care of the scale, but I believe you should add this to your samples … it’s a very simple & commun behaviour.
Thanks,
Patrick.
Patrick,
Try the following codes, hopefully this is what you are expecting.
int pixel = 10;
DistanceUnit distanceUnit = DistanceUnit.Meter;
ScreenPointF leftScreenPoint = new ScreenPointF(winformMap1.Width / 2.0f - pixel / 2.0f, winformMap1.Height / 2);
ScreenPointF rightScreenPoint = new ScreenPointF(winformMap1.Width / 2.0f + pixel / 2.0f, winformMap1.Height / 2);
double distance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(winformMap1.CurrentExtent, leftScreenPoint, rightScreenPoint, winformMap1.Width, winformMap1.Height, winformMap1.MapUnit, distanceUnit);
pointLayer.Open();
Collection<Feature> selectedFeatures = pointLayer.QueryTools.GetFeaturesWithinDistanceOf(e.WorldLocation,winformMap1.MapUnit,distanceUnit,distance, ReturningColumnsType.AllColumns);
pointLayer.Close();
Any more questions just let me know.
Thanks.
Yale
Posted By Patrick on 06-22-2009 01:50 AM
Yale,
additionnaly, GetFeaturesNearestTo does not seems to work. It returns a feature that is not the closest one to the user click.
here is my code, please help:
lp.Open();
selectedFeatures = lp.QueryTools.GetFeaturesNearestTo(e.WorldLocation,
theMap.MapUnit,
1,
ReturningColumnsType.AllColumns);
lp.Close();
if user clicks more than once, then it appears that every features are returned randomly; even some distant of many kilometers.
Patrick.
Patrick,
Thanks for your post!
I tested again about the GetFeaturesNearestTo API and it works. I tested the data from your post “Arbre.shp” pasted in following post as well as data from HowDoI samples:
gis.thinkgeo.com/Support/Dis…fault.aspx
Can you paste out some tested data you think about it does not work for you?
Thanks.
Yale
Yale,
your code with GetFeaturesWithinDistanceOf works perfectly for me.
Thank you.
Patrick.
Patrick,
Thanks, you are welcome!
Any more questions just let me know.
Yale.
Yale,
It looks like there is a regression on 3.0.331 for that feature.
When I'm using GetFeaturesWithinDistanceOf (feature),
With 3.0.113 it works regardless if the layer is projected or not.
With 3.0.331 it works only if the layer is not projected
at the opposite, GetFeaturesContaining (feature) is working regardless the projection in 3.0.331
Patrick.
Patrick,
I use the projected data “Arbre.shp” provided inanother post. I did not find any problems in any version.
Can you provide me more information to see what your problem is?
Sorry for the inconvenience now.
Thanks
Yale
Dear Yale,
here is, attached, a small sample that shows the problem.
Built here (vs2008, dotnet 3.5, vista 64 bits, built x86, ms 3.0.335) it does not work.
if WITHPROJECTIONGWS84 is not set then the collection return 1 or 2 features when you click on the map.
if WITHPROJECTIONGWS84 is set, the only difference is that the map is projected to WGS84 and the collection return 0 features when you click on the map.
Please note that I'm using winzip 12 that you may need for uncompressing.
Thank you for your help,
Patrick.
823-pbmProjection.zip (13.8 KB)
Patrick,
Thanks for your sample demo, I can see the problem with its help very easily.
I think there was some very difficult part to understand. When we do Spatial Query, the result almost ONLY depends on the RTree Index data (.idx, .ids), and in your sample App, you build the RTree based on the Non-projection data and Meter Unit. So please try the following codes in your MapClick event:
int pixel = 10;
DistanceUnit distanceUnit = DistanceUnit.Meter;
ScreenPointF leftScreenPoint = new ScreenPointF(winformMap1.Width / 2.0f - pixel / 2.0f, winformMap1.Height / 2);
ScreenPointF rightScreenPoint = new ScreenPointF(winformMap1.Width / 2.0f + pixel / 2.0f, winformMap1.Height / 2);
double distance = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(winformMap1.CurrentExtent, leftScreenPoint, rightScreenPoint, winformMap1.Width, winformMap1.Height, winformMap1.MapUnit, distanceUnit);
PointShape p = null;
if (ProjectionToWGS84 != null)
{
if (!ProjectionToWGS84.IsOpen) { ProjectionToWGS84.Open(); }
p = (PointShape)ProjectionToWGS84.ConvertToInternalProjection(e.WorldLocation);
}
else
{
p = e.WorldLocation;
}
worldLayer.Open();
Collection<Feature> selectedFeatures = worldLayer.QueryTools.GetFeaturesWithinDistanceOf(p, GeographyUnit.Meter, distanceUnit, distance, ReturningColumnsType.AllColumns);
MessageBox.Show(selectedFeatures.Count.ToString());
worldLayer.Close();
Any more questions just let me know.
Thanks.
Yale
Yale,
it’s not consistent that getfeaturewithinfeature takes external projected coords and getfeaturewithindistance tales internal projecteds coords.
Regards
Patrick.
Patrick,
Thanks for you’re sharing and posts!
I agree that the SpatialQuery logic should be same with GetFeaturesWithinDistance logic (this is API is not a standard SpatialQuery API).
I changed the logic of GetFeaturesWithinDistance to accept the Extennal Projected Coordinates system data; it will be available next version.
Thanks again for your suggestions and sharing.
Any more questions just let me know.
Yale
Yale,
will it be in 3.0.348 planed for tomorrow?
Patrick.
Patrick,
Yes, in build 3.0.348, the GetFeaturesWithinDistance will accept the external coordinate system data.
Any more question just let me know!
Thanks.
Yale
Yale,
unfortunatly, it still does not work for me with the same use case/simple sample.
I'm attaching the sample project to let you check.
I'm now getting and exception, regardless if I use internal or external projection, please send me a corrected version or a workaround.
MapSuiteCore:3.1.168;DesktopEdition:3.0.348
L'exception System.ArgumentOutOfRangeException n'a pas été gérée
Message="The decimal degree latitude value you provided was out of range.\r\nNom du paramètre : latitude"
Source="MapSuiteCore"
ParamName="latitude"
StackTrace:
à ThinkGeo.MapSuite.Core.x6d719af406ea4c2c.xcaea77dcf8ddb91c(Double x68af109c02c3871b, String x34decc57f0820440)
à ThinkGeo.MapSuite.Core.DecimalDegreesHelper.GetLongitudeDifferenceFromDistance(Double distance, DistanceUnit distanceUnit, Double latitude)
à ThinkGeo.MapSuite.Core.BaseShape.BufferCore(Double distance, Int32 quadrantSegments, BufferCapType bufferCapType, GeographyUnit shapeUnit, DistanceUnit distanceUnit)
à ThinkGeo.MapSuite.Core.BaseShape.Buffer(Double distance, GeographyUnit shapeUnit, DistanceUnit distanceUnit)
à ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesWithinDistanceOfCore(BaseShape targetShape, GeographyUnit unitOfData, DistanceUnit distanceUnit, Double distance, IEnumerable`1 returningColumnNames)
à ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesWithinDistanceOf(BaseShape targetShape, GeographyUnit unitOfData, DistanceUnit distanceUnit, Double distance, IEnumerable`1 returningColumnNames)
à ThinkGeo.MapSuite.Core.FeatureSource.GetFeaturesWithinDistanceOf(BaseShape targetShape, GeographyUnit unitOfData, DistanceUnit distanceUnit, Double distance, ReturningColumnsType returningColumnNamesType)
à ThinkGeo.MapSuite.Core.QueryTools.GetFeaturesWithinDistanceOf(BaseShape targetShape, GeographyUnit unitOfData, DistanceUnit distanceUnit, Double distance, ReturningColumnsType returningColumnNamesType)
à Post5813.Form1.winformsMap1_MapClick(Object sender, MapClickWinformsMapEventArgs e) dans D:\Temp\Post5873\Form1.cs:ligne 72
à ThinkGeo.MapSuite.DesktopEdition.WinformsMap.OnMapClick(MapClickWinformsMapEventArgs e)
à ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x1e882ae98c96da8b(InteractionArguments x195facd4ef5d753d)
à ThinkGeo.MapSuite.DesktopEdition.WinformsMap.xfeca3317d3c75bbb(Object xd9272088e65bd176, x6a8380ab1a7ebb4c xc2fd4c0ed406cdb7)
à ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.OnMouseEvent(x6a8380ab1a7ebb4c e)
à ThinkGeo.MapSuite.DesktopEdition.x5cd462d41be2f68a.AnalyseMouseMove(Double screenX, Double screenY, Double worldX, Double worldY)
à ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x7df2db1d74504263(Object xd9272088e65bd176, MouseEventArgs xc2fd4c0ed406cdb7)
à System.Windows.Forms.Control.WmMouseMove(Message& m)
à System.Windows.Forms.Control.WndProc(Message& m)
à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
à Post5813.Program.Main() dans D:\Temp\Post5873\Program.cs:ligne 18
à System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
à System.Threading.ThreadHelper.ThreadStart()
InnerException:
892-Post5873.zip (11.2 KB)
Patrick,
Thanks for your post!
I think you need to change one place to make it work:
Collection<Feature> selectedFeatures = worldLayer.QueryTools.GetFeaturesWithinDistanceOf(p, GeographyUnit.Meter, distanceUnit, distance, ReturningColumnsType.AllColumns);
Here, you should use Meter to reflect the Unit of the data, instead of using DecimalDegrees.
Let me know if you have any more problems.
Thanks.
Yale
Works perfectly, thank you.
Patrick.
Patrick,
You are always welcome!
Let me know if you have any more problems.
Thanks.
Yale