Convert WebMercatorExtent in Extent in Flex - apache-flex

I retrieve dynamically an Array with latidude longitude values that need to be calculated into an Extent so they fit exactly on a map (Adobe Flex). The layers I'm using in the Esri Map component are now:
<esri:ArcGISTiledMapServiceLayer id="arcgisonlineLayer" load="{trace(arcgisonlineLayer.version)}"
url="http://services.arcgisonline.nl/arcgis/rest/services/Basiskaarten/PDOK_BRT/MapServer"/>
<esri:WMSLayer url="{wmsLayerUrl}">
<esri:visibleLayers>
<s:ArrayList>
<fx:String>0</fx:String><!-- background colors -->
<fx:String>1</fx:String><!-- signs -->
<fx:String>2</fx:String><!-- red overview road map can be outcommented-->
<fx:String>3</fx:String><!-- lines -->
</s:ArrayList>
</esri:visibleLayers>
</esri:WMSLayer>
Before I used the standard Esri layers...
<esri:ArcGISTiledMapServiceLayer id="serviceLayer"
url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
visible="{viewModeButtonBar.selectedIndex == 0}"/>
<esri:ArcGISTiledMapServiceLayer
url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
visible="{viewModeButtonBar.selectedIndex == 1}"/>
..and I could use the WebMercatorExtent class to create an extend that would fit but now I need to use these layers and can't use the WebMercatorExtent because the service "http://services.arcgisonline.nl/arcgis/rest/services/Basiskaarten/PDOK_BRT/MapServer" uses
<esri:SpatialReference id="wgs" wkid="28992"/>
Which doesn't go with WebMercatorExtent. Anyone knows how to convert this com.esri.ags.geometry.WebMercatorExtent into an Extent?

It sounds like you need to convert a longitude/latitude Extent to an Extent in spatial reference 28992, right? If so, see the Flex sample on projecting geometries. Especially see the projectNow function. It uses GeometryService.project to project points from one coordinate system to another. You can use the same function to project extents from one coordinate system to another.

Here is how it's done in code. You need to declare as GeometryService that uses some an external webservice. This one is the sampleservice from Esri that might be out of order when you read this answer because there has been an upgrade. Best is to use your own arcgis service, for now I used this one:
http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer
Put in to Declarations
<fx:Declarations>
<esri:GeometryService id="geometryService"
concurrency="last"
fault="geometryService_faultHandler(event)"
projectComplete="projectCompleteHandler(event)"
showBusyCursor="true"
url="http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer"/>
</fx:Declarations>
Then create the WebMercatorExtent, create a SpatialReference you want your Geometry converted to and project it. The web service will provide the answer...
var wmExtent:WebMercatorExtent = new WebMercatorExtent(
_mapItemBounds.getSouthWest().lng(),
_mapItemBounds.getSouthWest().lat(),
_mapItemBounds.getNorthEast().lng(),
_mapItemBounds.getNorthEast().lat());
var outSR:SpatialReference = new SpatialReference(28992);
const projectParameters:ProjectParameters = new ProjectParameters;
projectParameters.geometries = [ wmExtent];
projectParameters.outSpatialReference = outSR;
geometryService.project(projectParameters);
...in the function
protected function projectCompleteHandler(event:GeometryServiceEvent):void
{
try
{
// Note: As of version 2.0, GeometryService returns geometries (instead of graphics)
var extent:Extent = (event.result as Array)[0] as Extent;
map.extent = extent;
}
catch (error:Error)
{
Alert.show(error.toString());
}
}

Related

How to set the "pcl::PointIndices" with the PCD file (existing point cloud sets)

I'm trying to implement a pointcloud background subtraction.
(eg. background.pcd = input.pcd - object.pcd)
I found following code
pcl::PointCloud<pcl::PointXYZ>::Ptr p_obstacles(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointIndices::Ptr inliers(new pcl::PointIndices());
pcl::ExtractIndices<pcl::PointXYZ> extract;
// Insert something.
extract.setInputCloud(p_obstacles);
extract.setIndices(inliers);
extract.setNegative(true);
extract.filter(*p_obstacles);
Removing points from a pcl::PointCloud<pcl::PointXYZRGB>
In my understating, the inliers is subtracted from the input.pcd
(inliers = object.pcd ??)
I have no idea how to set the inliers value with the pre-existing x,y,z values(pcd)
Thank you!
There's a getIndices() method in the PCLBase class: http://docs.pointclouds.org/1.8.1/classpcl_1_1_p_c_l_base.html#a058753dd4de73d3d0062fe2e452fba3c
Here's how to use it:
pcl::PCLBase<pcl::PointXYZ> base; // Instantiate the PCLBase class
base.setInputCloud(object_cloud); // Set input cloud before grabbing the indices
auto object_indices = base.getIndices();
extract.setIndices(object_indices);
You might need to include the header file
#include <pcl/pcl_base.h>
And if you haven't created a point cloud from your pcd file, you can follow this tutorial:
http://pointclouds.org/documentation/tutorials/reading_pcd.php

Trying to create point from X,Y, coordinate

I have used a formula to create an X and Y coordinate that I would like to create a point from. They are held in the attribute table, and I don't know how to use those points for the geometry. Here's the code:
cursor01 = arcpy.da.InsertCursor(OutPutCent,["SHAPE#X", "SHAPE#Y","Xcoord","Ycoord","totpop", "NAME","STATE_NAME","POLY_ID", "OBJECTID", "STATE_FIPS", "CNTY_FIPS", "FIPS", "FIPSnum","FIPS_NUMER" ])
#if row[0] >= 5.2:
cursor01.insertRow([XPoint,YPoint,centroid_X1,centroid_Y1,TotalPop1,thecntyName1,TheStateName1,idpoly1, idobject1, stateFIPS1, countyFIPS1, fips1, fipSnum1, fipsNumer1])
Any suggestions would be much appreciated I need to resolve this asap!
Best
This should probably be in gis.stackexchange.com.
Hard to tell what you're aiming for with that code, but I'll have a guess anyway...If you have existing points you want to relocate based on updated coordinates in an attribute table, try one of the following.
The simple no-scripting solution is this:
export your attribute table to csv
use Add XY Data to import the csv as a new layer
During the import process you can set the geometry to your Xcoord, Ycoord attribute fields, so the new dataset will have updated locations. Then just prune any records you don't want - looks like you're filtering on some value? Select by Attributes and delete rows that don't meet your condition.
Alternatively, a structurally correct template to update existing geometry with new coordinates from the attibute table is:
with arcpy.da.UpdateCursor(dataset, ['SHAPE#XY', 'point_unique_id_or_name', 'conditional_field', 'X_coord', 'Y_coord']) as cursor:
update_count = 0
for row in cursor:
if row[conditional_field_index] meets condition:
updated_point = (row[X_coord_index], row[Y_coord_index])
row[SHAPE#XY_index] = updated_point
cursor.updateRow(row)
print "{} location updated".format(row[point_unique_id_or_name_index])
update_count += 1
print "{} point locations updated".format(update_count)
You only need to reference relevant fields in the UpdateCursor - if they don't get referenced inside the for loop, don't include them.
Strongly advise you practice on a copy of your original dataset.
you need to import QPoint from QtCore:
from PyQt5.QtCore import QPoint
Then create a qpoint object:
_qpoint = QPoint()
Then add your desired x and y coordinates with the setX, and setY methods:
_qpoint.setX()
_qpoint.setY()
example:
_qpoint.setX(500)
_qpoint.setY(700)
beware of the capital X and Y in the 'set' method of the point object.
For more details, refer to this link.

Check if a point is inside a Polygon with the Google Maps API

I am developing an application using the Google Maps API v3, and I'm struggling to know how to find out if an X coordinate is inside a polygon.
You can use the Geometry Library of the Google Maps JS API. There's a function called containsLocation which tells you if a given LatLng is inside a Polygon. Note that it's a Polygon, not a Polyline. A Polyline is (as it says in the name) a line. So there is no such thing as a point being inside a polyline. You can check if a point is inside a Polygon with the containsLocation function.
google.maps.geometry.poly.containsLocation(somePoint, somePolygon)
In iOS it can be done by using GMSGeometryContainsLocation
Just create a GMSMutablePath, then fill with vertexes of your polygon and test the point.
Example(Swift 4.0):
func isWithin(_ point: CLLocationCoordinate2D) -> Bool {
let p = GMSMutablePath()
p.add(CLLocationCoordinate2D(latitude:30.02356126, longitude: -90.07047824))
p.add(CLLocationCoordinate2D(latitude:30.02501037, longitude: -90.0614231))
p.add(CLLocationCoordinate2D(latitude:30.03321034, longitude: -90.0617981))
p.add(CLLocationCoordinate2D(latitude:30.03192855, longitude: -90.07342815))
return GMSGeometryContainsLocation(point, p, true)
}
Note: If the last param of GMSGeometryContainsLocation is set to true, the GMSMutablePath is composed of great circle segments, otherwise it's of rhumb (loxodromic) segments.

Flex Charts: Can you use a minimum/maximum point from an IAxis for Cartesian Data Canvas to draw the entire width of the chart?

I have a chart with a DateTime axis as my horizontal and a Linear Axis for my vertical inside a Adobe Flex Line Chart. I want to use a Cartesian Data Canvas as a background element and draw custom set of background graphics mostly rectangles. When I have more than a single data point, the graphics work perfectly since they are supposed to span the width of the entire chart.
When I have only a single data point, however, I can't seem to get the rectangles to draw. Since I want my rectangles to span the entire width of the chart, I was thinking that I could get the x-coordinates from my axis, but this isn't working.
var canvasWidth:Number = chtCanvas.width;
var canvasHeight:Number = chtCanvas.height;
var minPt:Array;
var maxPt:Array;
var minPtDate:Date;
var maxPtDate:Date;
var minPtComplete:Point;
var maxPtComplete:Point;
// This works fine when there is more than 1 data point
minPt = chtCanvas.localToData(new Point(0, 0));
maxPt = chtCanvas.localToData(new Point(canvasWidth,canvasHeight));
//This does return a date object, but wont draw below
minPtDate = axisDate.minimum;
maxPtDate = axisDate.maximum;
//This returns NaN for the x
minPtComplete = chtCanvas.dataToLocal(minPtDate, axisSalary.minimum);
maxPtComplete = chtCanvas.dataToLocal(maxPtDate, axisSalary.maximum);
// Also tried this. Also returns NaN for the x value
//minPtComplete = chtCanvas.dataToLocal(axisDate.minimum, axisSalary.minumum);
//maxPtComplete = chtCanvas.dataToLocal(axisDate.maximum, axisSalary.maximum);
My actual drawing method is as follows:
// Tried this, works with points >2, does not draw with single data point
chtCanvas.drawRect(minPt[0], detail[i].MaxValue, maxPt[0], detail[i].MinValue);
//tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, detail[i].MaxValue, maxPtDate, detail[i].MinValue);
// Tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, minPt[1], maxPtDate, detail[i].MinValue);
// Tried this also
//chtCanvas.drawRect(minPtComplete.x, detail[i].MaxValue, maxPtComplete.x, detail[i].MinValue);
In this example, detail is an array collection of salary values and Im using the data value in the array to determine the vertical bounds of my rectangles.
I need to draw the rectangles the entire width of the chart (even when there is only a single data point). Thanks
Thanks to Heikki for his help. The following code works to use the axis values to draw on your Cartesian Data Canvas:
chtCanvas.drawRect(axisDate.minimum as Date, axisSalary.maximum, axisDate.maximum as Date, axisSalary.minimum);
Casting the values as Date really helped. The rest of the code used above is unecessary.
One thing to note, I was using a DateFormatter to format the date values from my data. What I didn't consider was that when using a DateTimeAxis, Flex will automatically add in extra dates to display on the axis. In my case, I was using a custom parse function to create MY points, but wasnt considering the points Flex was creating and also passing to my parse function (Therefore, they were not getting parsed correctly). Once I corrected this, the values laid out correctly in the case of multiple data points. I'm still having a bit of an issue with single data points and them not filling the chart entirely, but they are now drawing.
UPDATE:
Although there are signs of life, the minimum and maximum are still not drawing the entire width of the chart in some cases depending on the dataUnits and labelUnits combination.
UPDATE #2: SOLVED
Ok, so the axis does work as minimum/maximum values for the Cartesian Data Canvas but there is something important to remember. For a single point (and probably for multiple points as well, I just couldnt visually see the difference), when using a custom DateTimeAxis parse function such as what was in the Adobe Flex ASDoc tutorials:
private function axisDateParseFunction(item:String):Date
{
var inputDate:String = item;
inputDate = fmtDate.format(inputDate);
var newDate:Date = new Date();
if(inputDate)
{
var a:Array = inputDate.split('/');
newDate.fullYear = a[2];
newDate.month = a[0] - 1;
newDate.date = a[1];
newDate.hours = 0;
newDate.hoursUTC = 0;
newDate.minutes = 0;
newDate.minutesUTC = 0;
newDate.seconds = 0;
newDate.secondsUTC = 0;
newDate.milliseconds = 0;
newDate.millisecondsUTC = 0;
}
return newDate;
}
You MUST remember to set the UTC values as shown above also. Since the DateTimeAxis uses date AND time, when you create new Date objects, their time values also get set to the local system time. Remember to set those values to zero also or you will get points that dont exactly line up with your axis labels.

qt - In QGraphicsScene how to catch a particular item

I have so many things in my QGraphicsScene. The situation is I am creating a chessboard, and is using Graphics scene. So the QGraphicsScene is having so many QGraphicsPixmapItems. Now In this how can I get the King.
Update:
In this QGraphicsScene, I am adding QGraphicsPixmapItems which are nothing but coins(board,king,queen,soldiers,etc). Now if I want to move a particular coin say King, then How can I get it. There are some methods like using iterators. But is there any way to find a particular QGraphicsPixmapItem by it's name.
When you say you need to get the King, how do you make the difference in your program between the white King and the black one ?
If you need to get a Pawn, how do you know which one ? Anyone ? The first one you can find in your items ?
I haven't thought a lot about it, but maybe what you can do is using a QMap. The key would be a enumeration of the different pieces and the value would be a pointer to the relevant QGraphicsItem. Something like this :
enum Piece_e {
KING,
QUEEN,
ROOK1,
ROOK2,
...
PAWN1,
PAWN2,
...
};
QMap<Piece_e, QGraphicsPixmapItem*> WhitePiecesItems;
QMap<Piece_e, QGraphicsPixmapItem*> BlackPiecesItems;
When you are creating your scene and instanciating your pieces, you'll fill the map :
...
WhitePiecesItem[KING] = new QGraphicsPixmapItem(QPixmap("whiteking_pic"));
WhitePiecesItem[PAWN1] = new QGraphicsPixmapItem(QPixmap("whitepawn_pic"));
...
BlackPiecesItem[QUEEN] = new QGraphicsPixmapItem(QPixmap("whitequeen_pic"));
BlackPiecesItem[PAWN1] = new QGraphicsPixmapItem(QPixmap("whitepawn_pic"));
...
When you need to find the object corresponding to the white king, you could do something like this :
QGraphicsPixmapItem* pItem = WhitePiecesItem[KING];

Resources