Updating Extents

Oct 26, 2010 at 4:50 AM

I am able to move and edit shapes that I draw, but if I move a shape away from its original location, I can't re-select it by clicking on the current location, I have to click on its original location.  After a fair number of F11s I realized that the selection process relies on extents (not the envelope) and that when I move the shape I am only updating the envelope and not the extents.

How can I update the extents of a shape in a layer?  I don't see a layer.DataSet.UpdateExtents()...

Dave

Developer
Oct 26, 2010 at 3:21 PM
Here is the code slice from "UpdateEnvelopes()"

/// <summary>
/// After changing coordinates, this will force the re-calculation of envelopes on a feature
/// level as well as on the featureset level. If this featureset is in index mode,
/// this will update the shape extents instead.
/// </summary>
public void UpdateEnvelopes()
{
if (InternalDataSet != null)
{
InternalDataSet.UpdateEnvelopes();
return;
}
_envelope = new Envelope();
_extent = new Extent();
if (!_indexMode)
{
if (Features == null || Features.Count <= 0)
{
_extent = new Extent(-180, -90, 180, 90);
_envelope = _extent.ToEnvelope();
return;
}
foreach (IFeature feature in Features)
{
feature.UpdateEnvelope();
_envelope.ExpandToInclude(feature.Envelope);
}
_extent = new Extent(_envelope);
}
else
{
if (_shapeIndices == null || _shapeIndices.Count == 0)
{
_extent = new Extent(-180, -90, 180, 90);
_envelope = _extent.ToEnvelope();
return;
}
foreach (ShapeRange range in _shapeIndices)
{
range.CalculateExtents();
_extent.ExpandToInclude(range.Extent);
}
_envelope = _extent.ToEnvelope();
}
}

So theoretically, in both cases both the envelope and extent are updated, but depending on which mode you are in, it may use something you don't expect in order to calculate that extent. It should be synchronized with what is being drawn, but there may be a bug. If you moved features around, you may need to call myFeatureSet.InitializeVertices(); after making changes to ensure that the shape ranges match up, and then call UpdateEnvelopes(). If you are moving the raw vertex values around using the Vertex array, then you may need to call UpdateCoordinates() before calling UpdateEnvelopes. These sorts of things should be automated more correctly, and that is a known issue, but for now that should get you functional without requiring a bug fix.

Ted


On Mon, Oct 25, 2010 at 9:50 PM, davecove <notifications@codeplex.com> wrote:

From: davecove

I am able to move and edit shapes that I draw, but if I move a shape away from its original location, I can't re-select it by clicking on the current location, I have to click on its original location. After a fair number of F11s I realized that the selection process relies on extents (not the envelope) and that when I move the shape I am only updating the envelope and not the extents.

How can I update the extents of a shape in a layer? I don't see a layer.DataSet.UpdateExtents()...

Dave

Read the full discussion online.

To add a post to this discussion, reply to this email (DotSpatial@discussions.codeplex.com)

To start a new discussion for this project, email DotSpatial@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Oct 27, 2010 at 12:30 AM

I may be doing this in a way that is unexpected...  _featureSet.InitalizeVerticies() before UpdateEnvelopes() didn't seem to do the trick.

I am moving the shapes by re-writing the members of the feature's coordinates IList like so:

 _layer.DataSet.Features[EditFeatureIndex].Coordinates[i].X = _coord.X;                    

_layer.DataSet.Features[EditFeatureIndex].Coordinates[i].Y = _coord.Y; 

It seems to work fine other than the extents not keeping up with the move...

Dave

Oct 29, 2010 at 12:33 AM

Also, can someone tell me what is actually drawing the FeatureSet to the screen? Despite a lot F11's I can't seem to figure that out...

 

Dave

Developer
Oct 29, 2010 at 1:01 AM

At one time we were trying to host a DirectX map and a 2D GDI+ map simultaneously.  In order to support this kind of abstracted UI layer, it doesn't make sense to have a very low level interface called IRenderable and have symbology layers inherit from this to do the implementation because the necessary arguments (like a Graphics object or a DirectX Device) are totally different, and being able to pass a DirectX device would require a reference to DirectX, which would break the mono implementations.  Instead, it makes more sense to use the DotSpatial.Symbology level to store the common characteristics tied to a MapFrame architecture that is the same, so that both types of map can take advantage of the legend etc.  So we put the drawing at the highest level of inheritance instead.  DotSpatial.Controls.MapPolygonLayer, DotSpatial.Controls.MapLineLayer and DotSpatial.Controls.MapPointLayer are the classes that have the actual rendering instructions, and they are specifically designed to work in coordination with the GDI+ 2D map.

Ted

 

Developer
Oct 29, 2010 at 1:07 AM

As to the earlier post, I'm not sure what the bug is, but in the meantime, you should be able to use the Envelope on the geometries to set the Extent manually.  I know that loading from shapefiles may set the extents into a mode where it uses a "cached" extent, instead of calculating from the geometries or vertices each time its accessed, but the UpdateExtents in theory should affect that.  So you may need to look for some options related to that, I'm not sure.  If you still can't figure something out, we can open it up as an issue.