# Querying Raster Images

**URL:** <https://community.thinkgeo.com/t/querying-raster-images/3229>\
**Category:** WPF\
**Created:** [June 14, 2012, 8:33pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229 "2012-06-14T20:33:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![David11](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/8e8cbc/32.png) [@David11](https://community.thinkgeo.com/u/David11)\
**Post date:** [June 14, 2012, 8:33pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/1 "2012-06-14T20:33:44Z")

</div>

**Problem&nbsp;** -&nbsp;We&nbsp;need&nbsp;to&nbsp;be&nbsp;able&nbsp;to&nbsp;return&nbsp;a&nbsp;raster&nbsp;cell&nbsp;value&nbsp;for&nbsp;a&nbsp;given&nbsp;latitude&nbsp;and&nbsp;longitude??

**Background&nbsp;** -&nbsp;We&nbsp;are&nbsp;currently&nbsp;evaluating&nbsp;ThinkGeo&nbsp;Mapsuite&nbsp;to&nbsp;use&nbsp;in&nbsp;a&nbsp;Land-use&nbsp;modelling&nbsp;environment,&nbsp;whereby&nbsp;we&nbsp;are&nbsp;running&nbsp;water-balance&nbsp;simulations&nbsp;(using&nbsp;CUDA)&nbsp;at&nbsp;defined&nbsp;gridpoints&nbsp;using&nbsp;a&nbsp;series&nbsp;of&nbsp;vector&nbsp;and&nbsp;raster&nbsp;layers&nbsp;as&nbsp;inputs&nbsp;to&nbsp;the&nbsp;models.&nbsp;We&nbsp;need&nbsp;to&nbsp;be&nbsp;able&nbsp;to&nbsp;query&nbsp;the&nbsp;raster&nbsp;layers&nbsp;to&nbsp;return&nbsp;cell&nbsp;values&nbsp;at&nbsp;the&nbsp;predefined&nbsp;grid&nbsp;point&nbsp;locations.&nbsp;Obviously&nbsp;this&nbsp;is&nbsp;easy&nbsp;to&nbsp;do&nbsp;for&nbsp;vector&nbsp;layers&nbsp;(although&nbsp;its&nbsp;a&nbsp;bit&nbsp;slow&nbsp;in&nbsp;the&nbsp;interregation),&nbsp;but&nbsp;we&nbsp;can't&nbsp;see&nbsp;how&nbsp;to&nbsp;do&nbsp;this&nbsp;for&nbsp;the&nbsp;raster&nbsp;layers.&nbsp;Currently&nbsp;our&nbsp;raster&nbsp;data&nbsp;is&nbsp;in&nbsp;the&nbsp;Erdas&nbsp;Image&nbsp;format&nbsp;using&nbsp;the&nbsp;FDO&nbsp;libraries,&nbsp;although&nbsp;we&nbsp;are&nbsp;likely&nbsp;to&nbsp;use&nbsp;other&nbsp;raster&nbsp;formats&nbsp;as&nbsp;well.

**Possible&nbsp;Solutions** &nbsp;-&nbsp;Here&nbsp;are&nbsp;the&nbsp;options:

  
&nbsp;&nbsp;&nbsp;&nbsp;1. Use&nbsp;the&nbsp;current&nbsp;mapsuite&nbsp;tools&nbsp;to&nbsp;do&nbsp;this??&nbsp;Is&nbsp;this&nbsp;possible??&nbsp;I&nbsp;can't&nbsp;see&nbsp;that&nbsp;it&nbsp;is.
  
&nbsp;&nbsp;&nbsp;&nbsp;2. Use&nbsp;the&nbsp;FDO&nbsp;or&nbsp;GDAL&nbsp;libraries&nbsp;to&nbsp;query&nbsp;the&nbsp;data&nbsp;-&nbsp;we&nbsp;will&nbsp;be&nbsp;looking&nbsp;into&nbsp;this&nbsp;next.
  
&nbsp;&nbsp;&nbsp;&nbsp;3. Modify&nbsp;the&nbsp;mapsuite&nbsp;tools&nbsp;to&nbsp;achieve&nbsp;this&nbsp;-&nbsp;again&nbsp;-&nbsp;is&nbsp;this&nbsp;possible?
  

  

Coming&nbsp;from&nbsp;a&nbsp;modelling&nbsp;environment,&nbsp;this&nbsp;is&nbsp;an&nbsp;extremely&nbsp;important&nbsp;functionality&nbsp;to&nbsp;have&nbsp;in&nbsp;a&nbsp;GIS&nbsp;tool...&nbsp;I&nbsp;had&nbsp;just&nbsp;assumed&nbsp;that&nbsp;the&nbsp;ThinkGeo&nbsp;mapsuite&nbsp;would&nbsp;be&nbsp;able&nbsp;to&nbsp;do&nbsp;this,&nbsp;and&nbsp;was&nbsp;quite&nbsp;shocked&nbsp;to&nbsp;find&nbsp;that&nbsp;it&nbsp;doesn't&nbsp;seem&nbsp;to&nbsp;have&nbsp;the&nbsp;capability.&nbsp; **Does&nbsp;anyone&nbsp;have&nbsp;any&nbsp;suggestions&nbsp;or&nbsp;advice?**

Regards,&nbsp;  
  
David&nbsp;McClymont  
  
Principal&nbsp;Software&nbsp;Engineer  
  
DHM&nbsp;Environmental&nbsp;Software&nbsp;Engineering&nbsp;Pty&nbsp;Ltd

---

<div class="post-metadata">

**Author:** ![David](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@David](https://community.thinkgeo.com/u/David)\
**Post date:** [June 14, 2012, 9:36pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/2 "2012-06-14T21:36:57Z")

</div>

David,&nbsp;  
&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;Thank&nbsp;you&nbsp;for&nbsp;your&nbsp;very&nbsp;precise&nbsp;e-mail.&nbsp;&nbsp;I&nbsp;believe&nbsp;that&nbsp;we&nbsp;can&nbsp;do&nbsp;this&nbsp;without&nbsp;any&nbsp;changes.&nbsp;&nbsp;I&nbsp;will&nbsp;send&nbsp;you&nbsp;a&nbsp;proof&nbsp;of&nbsp;concept&nbsp;shortly.&nbsp;&nbsp;If&nbsp;this&nbsp;works&nbsp;then&nbsp;what&nbsp;I&nbsp;suggest&nbsp;is&nbsp;that&nbsp;we&nbsp;add&nbsp;a&nbsp;nice&nbsp;shortcut&nbsp;API&nbsp;to&nbsp;the&nbsp;RasterSource&nbsp;and&nbsp;RasterLayer&nbsp;base&nbsp;classes&nbsp;so&nbsp;this&nbsp;will&nbsp;be&nbsp;available&nbsp;to&nbsp;all&nbsp;of&nbsp;the&nbsp;inherited&nbsp;RasterLayers.&nbsp;&nbsp;Our&nbsp;approach&nbsp;to&nbsp;this&nbsp;will&nbsp;be&nbsp;to&nbsp;create&nbsp;a&nbsp;very&nbsp;small&nbsp;rectangle&nbsp;around&nbsp;the&nbsp;point&nbsp;and&nbsp;request&nbsp;a&nbsp;1x1&nbsp;bitmap&nbsp;from&nbsp;the&nbsp;RasterSource.&nbsp;&nbsp;After&nbsp;that&nbsp;we&nbsp;will&nbsp;get&nbsp;the&nbsp;cell&nbsp;value&nbsp;from&nbsp;the&nbsp;bitmap&nbsp;and&nbsp;pass&nbsp;it&nbsp;along.&nbsp;&nbsp;I&nbsp;believe&nbsp;this&nbsp;will&nbsp;work.&nbsp;&nbsp;When&nbsp;we&nbsp;implement&nbsp;the&nbsp;helper&nbsp;method&nbsp;we&nbsp;the&nbsp;Template&nbsp;Method&nbsp;Pattern&nbsp;as&nbsp;there&nbsp;are&nbsp;a&nbsp;number&nbsp;of&nbsp;raster&nbsp;layers&nbsp;we&nbsp;can&nbsp;easily&nbsp;get&nbsp;the&nbsp;cell&nbsp;value&nbsp;without&nbsp;using&nbsp;the&nbsp;trick&nbsp;above.&nbsp;&nbsp;I&nbsp;will&nbsp;let&nbsp;you&nbsp;know&nbsp;our&nbsp;results.&nbsp;  
&nbsp;&nbsp;  
&nbsp;David

---

<div class="post-metadata">

**Author:** ![David11](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/8e8cbc/32.png) [@David11](https://community.thinkgeo.com/u/David11)\
**Post date:** [June 16, 2012, 9:27am UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/3 "2012-06-16T09:27:17Z")

</div>

Thanks&nbsp;for&nbsp;your&nbsp;very&nbsp;prompt&nbsp;reply&nbsp;David.&nbsp;That&nbsp;would&nbsp;be&nbsp;awesome&nbsp;if&nbsp;you&nbsp;could&nbsp;show&nbsp;that&nbsp;this&nbsp;can&nbsp;be&nbsp;done.&nbsp;I'm&nbsp;sure&nbsp;there&nbsp;would&nbsp;be&nbsp;other&nbsp;modellers&nbsp;wanting&nbsp;to&nbsp;use&nbsp;MapSuite&nbsp;who&nbsp;would&nbsp;appreciate&nbsp;this&nbsp;functionality.

cheers  
  
David

---

<div class="post-metadata">

**Author:** ![David](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@David](https://community.thinkgeo.com/u/David)\
**Post date:** [June 17, 2012, 11:48pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/4 "2012-06-17T23:48:08Z")

</div>

&nbsp;David,

&nbsp;  
&nbsp;&nbsp;Below&nbsp;is&nbsp;the&nbsp;code&nbsp;that&nbsp;should&nbsp;help&nbsp;you&nbsp;get&nbsp;the&nbsp;pixel&nbsp;value.&nbsp;If&nbsp;this&nbsp;lines&nbsp;up&nbsp;with&nbsp;your&nbsp;expectation&nbsp;we&nbsp;can&nbsp;integrate&nbsp;it&nbsp;into&nbsp;the&nbsp;daily&nbsp;builds&nbsp;so&nbsp;it&nbsp;will&nbsp;be&nbsp;tightly&nbsp;couples&nbsp;with&nbsp;the&nbsp;product.&nbsp;&nbsp;We&nbsp;look&nbsp;forward&nbsp;to&nbsp;your&nbsp;suggestions&nbsp;and&nbsp;comments.  
&nbsp;  
David  
&nbsp;  
  
`using System.Drawing;using ThinkGeo.MapSuite.Core;namespace ThinkGeo.MapSuite.Core{    static class RasterSourceHelper    {        public static GetPixelValueResult GetPixelValue(RasterSource rasterSource, PointShape pointShape)        {            GetPixelValueResult getPixelValueResult = new GetPixelValueResult();            RectangleShape boudingBox = rasterSource.GetBoundingBox();            // Here we times 1.0000000000001 to make sure the width/height is a little larger than a cell            double pixelWidth = boudingBox.Width / rasterSource.GetImageWidth() * 1.0000000000001;            double pixelHeight = boudingBox.Height / rasterSource.GetImageHeight() * 1.0000000000001;            double minX = boudingBox.LowerLeftPoint.X;            double minY = boudingBox.LowerLeftPoint.Y;            double maxX = boudingBox.UpperRightPoint.X;            double maxY = boudingBox.UpperRightPoint.Y;            if (pointShape.X < minX || pointShape.X > maxX || pointShape.Y < minY || pointShape.Y > maxY)            {                // The input pointshape is not within the extent of rasterSource.                getPixelValueResult.IsValid = false;                return getPixelValueResult;            }            double smallRectangleShapeMinX = pointShape.X - pixelWidth;            double smallRectangleShapeMaxY = pointShape.Y + pixelHeight;            double smallRectangleShapeMaxX = pointShape.X;            double smallRectangleShapeMinY = pointShape.Y;            if (pointShape.X - pixelWidth < minX) // left            {                smallRectangleShapeMinX = pointShape.X;                smallRectangleShapeMaxX = pointShape.X + pixelWidth;            }            else if (pointShape.X + pixelWidth > maxX)// right            {                smallRectangleShapeMinX = pointShape.X - pixelWidth;                smallRectangleShapeMaxX = pointShape.X;            }            if (pointShape.Y + pixelHeight > maxY) // top            {                smallRectangleShapeMinY = pointShape.Y - pixelHeight;                smallRectangleShapeMaxY = pointShape.Y;            }            else if (pointShape.Y - pixelHeight < minY) // bottom            {                smallRectangleShapeMinY = pointShape.Y;                smallRectangleShapeMaxY = pointShape.Y + pixelHeight;            }            RectangleShape smallRectangleShape = new RectangleShape(smallRectangleShapeMinX, smallRectangleShapeMaxY, smallRectangleShapeMaxX, smallRectangleShapeMinY);            GeoImage geoImage = rasterSource.GetImage(smallRectangleShape, 1, 1);            Bitmap bitmap = new Bitmap(geoImage.GetImageStream(new GdiPlusGeoCanvas()));                        Color color = bitmap.GetPixel(0, 0);            bitmap.Dispose();            geoImage.Dispose();            getPixelValueResult.PixelValue = new GeoColor(color.A, color.R, color.G, color.B);            getPixelValueResult.IsValid = true;            return getPixelValueResult;        }    }}using ThinkGeo.MapSuite.Core;namespace ThinkGeo.MapSuite.Core{    class GetPixelValueResult    {        private bool isValid;        private GeoColor pixelValue;        public GetPixelValueResult()            :this(false, new GeoColor())        { }        public GetPixelValueResult(bool isValid, GeoColor pixelValue)        {            this.isValid = isValid;            this.pixelValue = pixelValue;        }        public bool IsValid        {            get { return isValid; }            set { isValid = value; }        }        public GeoColor PixelValue        {            get { return pixelValue; }            set { pixelValue = value; }        }    }}`

---

<div class="post-metadata">

**Author:** ![David11](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/8e8cbc/32.png) [@David11](https://community.thinkgeo.com/u/David11)\
**Post date:** [July 28, 2012, 10:39pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/5 "2012-07-28T22:39:29Z")

</div>

Thankyou&nbsp;very&nbsp;much&nbsp;for&nbsp;this...&nbsp;sorry&nbsp;for&nbsp;the&nbsp;delay&nbsp;in&nbsp;replying,&nbsp;I'm&nbsp;about&nbsp;to&nbsp;get&nbsp;back&nbsp;to&nbsp;this&nbsp;problem&nbsp;next&nbsp;week.

Some&nbsp;initial&nbsp;impressions,&nbsp;I'd&nbsp;be&nbsp;interested&nbsp;to&nbsp;see&nbsp;the&nbsp;performance&nbsp;of&nbsp;this&nbsp;-&nbsp;not&nbsp;sure&nbsp;what&nbsp;sort&nbsp;of&nbsp;a&nbsp;hit&nbsp;the&nbsp;1x1&nbsp;bitmap&nbsp;creation&nbsp;will&nbsp;have&nbsp;as&nbsp;I'll&nbsp;be&nbsp;firing&nbsp;off&nbsp;tens&nbsp;of&nbsp;thousands&nbsp;of&nbsp;requests&nbsp;-&nbsp;nevertheless&nbsp;-&nbsp;you've&nbsp;given&nbsp;me&nbsp;the&nbsp;idea&nbsp;to&nbsp;make&nbsp;this&nbsp;work&nbsp;-&nbsp;I'd&nbsp;probably&nbsp;want&nbsp;to&nbsp;export&nbsp;a&nbsp;complete&nbsp;bitmap&nbsp;based&nbsp;on&nbsp;grid&nbsp;size&nbsp;that&nbsp;I&nbsp;want&nbsp;to&nbsp;query,&nbsp;where&nbsp;each&nbsp;pixel&nbsp;would&nbsp;compare&nbsp;exactly&nbsp;to&nbsp;my&nbsp;target&nbsp;grid&nbsp;-&nbsp;I&nbsp;would&nbsp;guess&nbsp;that&nbsp;there&nbsp;would&nbsp;be&nbsp;come&nbsp;distortion&nbsp;(averaging)&nbsp;of&nbsp;the&nbsp;pixel&nbsp;colours&nbsp;-&nbsp;but&nbsp;this&nbsp;would&nbsp;probably&nbsp;be&nbsp;a&nbsp;benefit&nbsp;(&nbsp;a&nbsp;crude&nbsp;form&nbsp;of&nbsp;spatial&nbsp;averaging).&nbsp;I'll&nbsp;give&nbsp;both&nbsp;a&nbsp;go&nbsp;and&nbsp;compare...&nbsp;I'll&nbsp;let&nbsp;you&nbsp;know&nbsp;the&nbsp;result.

I've&nbsp;got&nbsp;another&nbsp;question&nbsp;for&nbsp;querying&nbsp;a&nbsp;vector&nbsp;layer&nbsp;which&nbsp;I&nbsp;will&nbsp;post&nbsp;as&nbsp;a&nbsp;new&nbsp;topic.

cheers

David&nbsp;McClymont

DHM&nbsp;Environmental&nbsp;Software&nbsp;Engineering.

---

<div class="post-metadata">

**Author:** ![David](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/d/aeb1de/32.png) [@David](https://community.thinkgeo.com/u/David)\
**Post date:** [July 28, 2012, 11:53pm UTC](https://community.thinkgeo.com/t/querying-raster-images/3229/6 "2012-07-28T23:53:34Z")

</div>

David,&nbsp;  
&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;I’m&nbsp;glad&nbsp;I&nbsp;was&nbsp;able&nbsp;to&nbsp;spark&nbsp;some&nbsp;ideas.&nbsp;&nbsp;If&nbsp;the&nbsp;pixels&nbsp;you&nbsp;are&nbsp;getting&nbsp;are&nbsp;around&nbsp;the&nbsp;same&nbsp;area&nbsp;then&nbsp;I&nbsp;suggest&nbsp;that&nbsp;maybe&nbsp;we&nbsp;create&nbsp;another&nbsp;function&nbsp;where&nbsp;you&nbsp;first&nbsp;pass&nbsp;in&nbsp;the&nbsp;bounds&nbsp;of&nbsp;the&nbsp;area&nbsp;where&nbsp;you&nbsp;will&nbsp;search,&nbsp;maybe&nbsp;include&nbsp;some&nbsp;limit&nbsp;and&nbsp;then&nbsp;we&nbsp;query&nbsp;the&nbsp;raster&nbsp;for&nbsp;that&nbsp;area.&nbsp;&nbsp;Next&nbsp;we&nbsp;allow&nbsp;you&nbsp;to&nbsp;get&nbsp;pixel&nbsp;values&nbsp;based&nbsp;in&nbsp;the&nbsp;region&nbsp;which&nbsp;should&nbsp;be&nbsp;very&nbsp;fast&nbsp;since&nbsp;we&nbsp;are&nbsp;querying&nbsp;just&nbsp;one&nbsp;bitmap.&nbsp;&nbsp;Another&nbsp;option&nbsp;is&nbsp;to&nbsp;add&nbsp;support&nbsp;for&nbsp;this&nbsp;at&nbsp;the&nbsp;lowest&nbsp;levels&nbsp;around&nbsp;where&nbsp;we&nbsp;call&nbsp;the&nbsp;third&nbsp;party&nbsp;libraries&nbsp;like&nbsp;MrSid&nbsp;and&nbsp;ECW.&nbsp;&nbsp;In&nbsp;this&nbsp;way&nbsp;it&nbsp;is&nbsp;the&nbsp;quickest&nbsp;possible&nbsp;way&nbsp;to&nbsp;get&nbsp;the&nbsp;pixel.&nbsp;&nbsp;of&nbsp;course&nbsp;if&nbsp;you&nbsp;know&nbsp;a&nbsp;region&nbsp;then&nbsp;its&nbsp;better&nbsp;to&nbsp;know&nbsp;that&nbsp;and&nbsp;it&nbsp;may&nbsp;even&nbsp;be&nbsp;faster.&nbsp;  
&nbsp;&nbsp;  
&nbsp;David
