Question

Performing a math operation on a value returned by an XQuery

  • 18 October 2013
  • 9 replies
  • 4 views

Badge +6
Hi,

 

 

I am using the the following functions for extracting X and Y coordinates values from my geometry:

 

 

<COORD> <X>{geom:get-x-coord()}</X> <Y>{geom:get-y-coord()}</Y> </COORD>

 

 

This works well and  I get something looking like this:

 

 

<?xml version="1.0" encoding="UTF-8"?> <TTSACTION TTSActionId="02A6F0EB5EF98599202DDC830A0000BB"> <CREATEROAD> <LINESTRING> <COORD> <X>4.123456</X> <Y>50.123456</Y> </COORD><COORD> <X>5.789456</X> <Y>49.789456</Y> </COORD><COORD> <X>5.123456</X> <Y>50.456123</Y> </COORD> </LINESTRING>         </CREATEROAD> </TTSACTION>

 

 

However I need to multiply the X and Y values by 10000000 (otherwise I will not be in line with the XSD definitions).

 

 

I tried using the @double() function before multiplying the result by the constant but it is not supported, or at least not in the way I did it.

 

 

It would return the following without performing any calcualtion:

 

 

<?xml version="1.0" encoding="UTF-8"?> <TTSACTION TTSActionId="02A6F0EB5EF98599202DDE4B62000099"> <CREATEROAD> <LINESTRING> <COORD> <X>int(10000000*(double(geom:get-x-coord())))</X> <Y>int(10000000*(double(geom:get-y-coord())))</Y> </COORD><COORD> <X>int(10000000*(double(geom:get-x-coord())))</X> <Y>int(10000000*(double(geom:get-y-coord())))</Y> </COORD><COORD> <X>int(10000000*(double(geom:get-x-coord())))</X> <Y>int(10000000*(double(geom:get-y-coord())))</Y> </COORD> </LINESTRING>         </CREATEROAD> </TTSACTION>

 

 

I must be overlooking something about the syntax. 

 

 

Thanks in advance for your suggestions!

 

 

Best regards,

 

 

Olivier

 


9 replies

Userlevel 4
Hi,

 

 

it might be both easier and more transparent if you used an ExpressionEvaluator to multiply the coordinate values.

 

 

David
Badge +6
Hi,

 

 

Thanks. Actually I am looking for a solution within the XMLTemplater transformer in order to take advantage from the Geometry Template option which does exactly what I need (looking into the geometry without the need to extract it beforehand). I can call it from the Root part using {geom:process-points( "GEOM" )} and have all the shape point coordinates be returned according to my geometry subtemplate.

 

I know that expressions work well in the ExpressionEvaluator transformer but I don't see how it could be used for this if it is positioned after the XMLTemplator (coordinates are embedded within the XML).

 

 

Best regards,

 

 

Olivier

 

 

Userlevel 2
Badge +17
Hi Olivier,

 

 

Since I'm not familiar with XQuery functions, I cannot provide exactly what you need. But, the Scaler transformer (and the CoordinateRounder if necessary) can be used to scale geometries without extracting coordinates. For your information.

 

 

Takashi
Userlevel 4
Badge +13
Hi Oliver,

 

 

You can try the Xpath numeric operand as described here:

 

http://www.w3.org/TR/xpath-functions/#func-numeric-multiply
Badge +6
Hi,

 

 

Thanks to you too Takashi!

 

Using the Scaler transformer (followed by the CoordinateRounder in order to ensure that there is no remaining decimal) is a very creative idea. I just tried it and the only remaining issue with that solution is that my coordinates now appear in scientific notation inside the XML:

 

 

<?xml version="1.0" encoding="UTF-8"?> <TTSACTION TTSActionId="55596A665A55C000202DE58D3E000017"> <CREATEROAD> <LINESTRING> <COORD> <X>4.123456E7</X> <Y>5.0123456E8</Y> </COORD><COORD> <X>5.789456E7</X> <Y>4.9789456E8</Y> </COORD><COORD> <X>5.123456E7</X> <Y>5.0456123E8</Y> </COORD> </LINESTRING>         </CREATEROAD> </TTSACTION>

 

 

I also just tried using the ReplaceString and PadRight FME functions around the {geom:get-x-coord()} and {geom:get-y-coord()} expressions in the XMLTemplator but that doesn't seem to work either.

 

 

In any case, thank you very much for your suggestion!

 

 

Best regards,

 

 

Olivier
Badge +6
Hi Itay,

 

 

I have indeed tried using this XQuery function but nothing is being calculated.

 

 

I used the following syntax:

 

 

<COORD> <X>op:numeric-multiply({geom:get-x-coord()},10000000)</X> <Y>op:numeric-multiply({geom:get-y-coord()},10000000)</Y> </COORD>

 

 

It returns:

 

 

<COORD> <X>op:numeric-multiply(4.123456,10000000)</X> <Y>op:numeric-multiply(50.123456,10000000)</Y> </COORD><COORD> <X>op:numeric-multiply(5.789456,10000000)</X> <Y>op:numeric-multiply(49.789456,10000000)</Y> </COORD><COORD> <X>op:numeric-multiply(5.123456,10000000)</X> <Y>op:numeric-multiply(50.456123,10000000)</Y> </COORD>

 

 

Putting the function in between {} does not help either. Do you have any suggestion?

 

 

Thank you!

 

 

Olivier  
Userlevel 4
Badge +13
Hi Olivier,

 

 

The only suggestion I have, maintaining the data in the XML is to use xfMaps with the XMLFeatureMapper to recreate the point objects and then use the expression evaluator / scaler on them.

 

This wont be my favourite way to do it since xfmaps can be complicated to create and are static.

 

Therefore I would firstly write the xml and then read it with the XML reader using the feature paths to create the geomtries and scale/multiply the coordinate values.

 

Hope this helps,

 

Itay
Userlevel 4
Badge +13
and , if applicable, scale the objects coordinates BEFORE featching them....
Userlevel 2
Badge +17

I found XQuery operators can be used here.

<COORD>
<X>{xs:integer(geom:get-x-coord() * 100000000)}</X>
<Y>{xs:integer(geom:get-y-coord() * 100000000)}</Y>
</COORD>

Reply