<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-priority:99;
mso-style-link:"Balloon Text";
font-family:"Tahoma","sans-serif";}
span.EmailStyle19
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:#1F497D;}
span.EmailStyle20
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:#1F497D;}
span.EmailStyle21
{mso-style-type:personal;
font-family:"Calibri","sans-serif";
color:#1F497D;}
span.EmailStyle22
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Well, +1 again.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Voting has been open for some time now. Final votes are due tomorrow, by 5pm ET.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Greg<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> fdo-internals-bounces@lists.osgeo.org [mailto:fdo-internals-bounces@lists.osgeo.org]
<b>On Behalf Of </b>Trevor Wekel<br>
<b>Sent:</b> Tuesday, October 23, 2012 5:54 PM<br>
<b>To:</b> FDO Internals Mail List<br>
<b>Subject:</b> Re: [fdo-internals] RFC 65 Implement Resampling for GDAL Provider<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Ok. Thanks Greg. I make a couple of small updates to the RFC and attached the latest code yesterday.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Regards,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Trevor
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">
<a href="mailto:fdo-internals-bounces@lists.osgeo.org">fdo-internals-bounces@lists.osgeo.org</a>
<a href="mailto:[mailto:fdo-internals-bounces@lists.osgeo.org]">[mailto:fdo-internals-bounces@lists.osgeo.org]</a>
<b>On Behalf Of </b>Greg Boone<br>
<b>Sent:</b> October 23, 2012 3:52 PM<br>
<b>To:</b> FDO Internals Mail List<br>
<b>Subject:</b> Re: [fdo-internals] RFC 65 Implement Resampling for GDAL Provider<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I think the RFC is ok, the final say on the code review is Frank.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Greg<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">
<a href="mailto:fdo-internals-bounces@lists.osgeo.org">fdo-internals-bounces@lists.osgeo.org</a> [<a href="mailto:fdo-internals-bounces@lists.osgeo.org">mailto:fdo-internals-bounces@lists.osgeo.org</a>]
<b>On Behalf Of </b>Trevor Wekel<br>
<b>Sent:</b> Sunday, October 21, 2012 10:56 PM<br>
<b>To:</b> FDO Internals Mail List<br>
<b>Subject:</b> Re: [fdo-internals] RFC 65 Implement Resampling for GDAL Provider<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Hi Frank,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I have attached an updated patch to RFC 65 with the CPLPrintPointer modification and compile fixes [Makefile.am updates] for Linux. The code compiles
and the FDO unit tests are clean on VC10 32bit Windows, VC10 64bit Windows, and 32bit CentOS 5.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I was also able to verify the functionality visually in MapGuide on all three platforms. No code changes are required for MapGuide. Just add
the following parameter to the feature source XML document:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"><Parameter><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"> <Name></span><span lang="EN-CA" style="font-family:"Courier New";color:black">ResamplingMethod</span><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"></Name><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"> <Value></span><span lang="EN-CA" style="font-family:"Courier New";color:black">bilinear</span><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"></Value><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-family:"Courier New";color:darkmagenta"></Parameter></span><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">If everyone is ok with the RFC “as is”, can we get it approved? I can check the code in the next day or so.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Regards,<br>
Trevor<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">
<a href="mailto:fdo-internals-bounces@lists.osgeo.org">fdo-internals-bounces@lists.osgeo.org</a>
<a href="mailto:[mailto:fdo-internals-bounces@lists.osgeo.org]">[mailto:fdo-internals-bounces@lists.osgeo.org]</a>
<b>On Behalf Of </b>Frank Warmerdam<br>
<b>Sent:</b> October 12, 2012 5:30 PM<br>
<b>To:</b> FDO Internals Mail List<br>
<b>Subject:</b> Re: [fdo-internals] RFC 65 Implement Resampling for GDAL Provider<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span lang="EN-CA"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-CA">On Fri, Oct 12, 2012 at 3:20 PM, Trevor Wekel <<a href="mailto:trevor_wekel@otxsystems.com" target="_blank">trevor_wekel@otxsystems.com</a>> wrote:<o:p></o:p></span></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Hi Frank,</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I was not aware of VRTWarpedDataset so did not consider it initially.</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">So I took a quick look at vrtwarped.cpp. I have a question. In vrtwarped.cpp, the
ProcessBlock() seems to cache the results of the warp operation (GDALCopyWords around line 1174) into each raster band. Does this mean that all blocks will end up being cached?</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA">Trevor,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA">Yes, VRTWarpedDataset will always push produced tiles into the GDAL block cache. Note that most drivers go through the block cache too.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"> <o:p></o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">For FDO, we basically call a ReadNext() to suck the contents of the tile into a buffer
supplied by the caller. The ReadNext() drives the calls to _getTile(). As far as I can tell, our access pattern is linear and we only access each tile once. If we switch to using VRTWarpedDataset, will we have to call ProcessBlock() for each tile? Will
this end up caching all the blocks as we do the linear read?</span><span lang="EN-CA"><o:p></o:p></span></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"> In a web context, the ideal would be a long lived server which keeps around the VRTWarpedDataset for subsequent use. I not sure how practical that is in the FDO/MapGuide use case. In this situation caching the blocks
can help subsequent views but there might be better other layers at which to do that.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">As an alternative to using VRTWarpedDataset, would it be ok to instantiate a GDALWarpOperation
as a member of the FdoRfpStreamReaderByTileResample? Pseudo code would be something like this:</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">FdoRfpStreamReaderGdalByTileResample::FdoRfpStreamReaderGdalByTileResample()</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">{</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">m_warpOp = new GDALWarpOperation();</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">}</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">FdoRfpStreamReaderGdalByTileResample::_getTile()</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">{</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">warpOptions = GDALCreateWarpOptions();</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">// populate warp options</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">m_warpOp->Initialize(warpOptions);</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">m_warpOp->WarpRegion(0,0,origXSize,origYSize);</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span lang="EN-CA" style="font-size:9.5pt;font-family:Consolas">}</span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> </span><span lang="EN-CA"><o:p></o:p></span></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span lang="EN-CA" style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">This may improve the speed of the _getTile() call if a) Initialize() can be called more
than once and b) the new GDALWarpOperation() does a lot of setup work</span><span lang="EN-CA"><o:p></o:p></span></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA">It is more likely to be the Iniitalize() that is expensive and reinitialzing an existing WarpOperation is not a well trod path and likely to lead to pain. I advise against it. In retrospect, sticking with your existing
approach is likely ok but you might want to get a sense of how much time is spent in the setup code vs. the actual warping. Larger tiles will help.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA">Best regards,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span lang="EN-CA"> <o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span lang="EN-CA">-- <br>
---------------------------------------+--------------------------------------<br>
I set the clouds in motion - turn up | Frank Warmerdam, <a href="mailto:warmerdam@pobox.com" target="_blank">
warmerdam@pobox.com</a><br>
light and sound - activate the windows | <a href="http://pobox.com/~warmerdam" target="_blank">
http://pobox.com/~warmerdam</a><br>
and watch the world go round - Rush | Geospatial Software Developer<o:p></o:p></span></p>
</div>
</body>
</html>