// // build a root node for the layer then add child nodes to that root before adding the root // to the topNode // private static void CreateTreeLayers(TreeNode parentTree, Layer thisLayer, int layerNumber) { string thisLayerName; DebugUtil.WriteLine(); DebugUtil.WriteLine("++++++ New Layer: " + thisLayer.GetName() + ". Layer Number: " + layerNumber + ". Feature Count: " + thisLayer.GetFeatureCount(1).ToString() + " +++++"); DebugUtil.WriteLine(); // build sub-trees by layer. Under that there will be sub-treas for Features and Fields TreeNode thisLayerTree = new TreeNode(); // create a new root node for this layer and name it thisLayerName = thisLayer.GetName(); thisLayerTree.Name = thisLayerName; thisLayerTree.Text = thisLayerName; //TreeUtil.AddChildNode(thisLayerTree, "Feature Count = " + thisLayer.GetFeatureCount(1).ToString()); // get the features CreateTreeFeatures(thisLayerTree, thisLayer); // add this layer to the parent tree parentTree.Nodes.Add(thisLayerTree); }
// // add a childnode with the text contained in "caption" // add another childnode under that (grandchild) to that that contains the data in "value" // of "value" is emptry, then skip that part // public static void AddChildNode(TreeNode parent, string caption, string value) { TreeNode thisChild, thisGrandChild; // add caption as a child node thisChild = new TreeNode(); thisChild.Name = caption; thisChild.Text = caption; if (value != null && value != "") { // add values as a Grand Child thisGrandChild = new TreeNode(); thisGrandChild.Name = value; thisGrandChild.Text = value; thisChild.Nodes.Add(thisGrandChild); } parent.Nodes.Add(thisChild); #if false //generates a lot of output and is redundant if you are printing from your app DebugUtil.WriteLine("Child Node added. Caption: " + caption); if (value != "") { DebugUtil.WriteLine(" Value: " + value + "."); } #endif }
private static void PrintDriversGdal() { if (DebugUtil._debug) { var num = Gdal.GetDriverCount(); for (var i = 0; i < num; i++) { var driver = Gdal.GetDriver(i); DebugUtil.WriteLine(string.Format("GDAL {0}: {1}-{2}", i, driver.ShortName, driver.LongName)); } } }
private static void PrintDriversOgr() { if (DebugUtil._debug) { var num = Ogr.GetDriverCount(); for (var i = 0; i < num; i++) { var driver = Ogr.GetDriver(i); DebugUtil.WriteLine(string.Format("OGR {0}: {1}", i, driver.name)); } } }
// simple function that only opens the driver and returns a pointer to the provider private static DataSource OpenMap(String fileName) { // save the dataset name _S57FileName = fileName; // register all the drivers so we can find the one we need - this is slow if debug output is on Ogr.RegisterAll(); // open the specified fileName with update set to R/O (=0) ds = Ogr.Open(fileName, 0); if (ds == null) { MessageBox.Show("Ogr.Open returned a zero. Make sure your file pathname is correct."); _S57DataSource = null; _S57FileName = ""; } else { DebugUtil.WriteLine("DataSource is: " + ds.ToString()); DebugUtil.WriteLine("DataSource Name is: " + ds.name.ToString()); _S57DataSource = ds; _S57DataSourceName = ds.name; Driver drv = ds.GetDriver(); _S57Driver = drv; if (drv == null) { MessageBox.Show("S-57 driver is null. Make sure your drivers are in the correct directory and GDAL_DRV points to them."); ds = null; } else { DebugUtil.WriteLine("Driver is: " + drv.ToString()); } } return(ds); }
/* -------------------------------------------------------------------- * Reading the Field Definitions. * * These define how to interpret the Features (next section). They do * do not need to be added to the tree, but are used to interpret the * Features. * * --------------------------------------------------------------------*/ protected static void CreateTreeFeatures(TreeNode parentLayerTree, Layer thisLayer) { FeatureDefn featureDefn; // // These are fields from the DSID layer. They have odd names, but we need this data. // string[] DSIDList = { "DSID_EXPP", "DSID_INTU", "DSID_DSNM", "DSID_EDTN", "DSID_UPDN", "DSID_UADT", "DSID_ISDT", "DSID_STED", "DSID_PRSP", "DSID_PSDN", "DSID_PRED", "DSID_PROF", "DSID_AGEN", "DSID_COMT", "DSSI_DSTR", "DSSI_AALL", "DSSI_NALL", "DSSI_NOMR", "DSSI_NOCR", "DSSI_NOGR","DSSI_NOLR", "DSSI_NOIN", "DSSI_NOCN", "DSSI_NOED", "DSSI_NOFA", "DSPM_HDAT", "DSPM_VDAT", "DSPM_SDAT", "DSPM_CSCL", "DSPM_DUNI", "DSPM_HUNI","DSPM_PUNI", "DSPM_COUN", "DSPM_COMF", "DSPM_SOMF", "DSPM_COMT" }; // This is the list of feature fields used to contain names. Not all objects are nameed. Some that are not named have useful comments. // This is order dependenet. string[] featureNameList = { "OBJNAM", "CATSEA", "CATLND" }; Feature feature; TreeNode featureTree; FieldDefn fieldDefn; int objIndex; // index used to search within fields string fieldName; // name of a specific field string fieldValue; // value for a specific field #if false // there is litte point in adding the field defintions to the tree or the output files other than diagnostics // if you want to turn this on change or remove the #if/#endif. FYI it makes bot the file and the tree much larger // and therefore slower to build and display. FieldDefn fieldDefn; // variable for local fields // DebugUtil.WriteLine(" *** Field Definitions ***"); for (int iAttr = 0; iAttr < featureDefn.GetFieldCount(); iAttr++) { // get the collection of field information fieldDefn = featureDefn.GetFieldDefn(iAttr); // add a new local root node to hold this field and give it this field name thisFieldRoot = new TreeNode(fieldDefn.GetName()); TreeUtil.AddChildNode(thisFieldRoot, "Field Name", fieldDefn.GetName()); TreeUtil.AddChildNode(thisFieldRoot, "Name Ref", fieldDefn.GetNameRef()); TreeUtil.AddChildNode(thisFieldRoot, "Type Name", fieldDefn.GetTypeName()); TreeUtil.AddChildNode(thisFieldRoot, "Field Type", fieldDefn.GetFieldType().ToString()); TreeUtil.AddChildNode(thisFieldRoot, "Width", fieldDefn.GetWidth().ToString()); TreeUtil.AddChildNode(thisFieldRoot, "Precision", fieldDefn.GetPrecision().ToString()); fieldDefn.GetTypeName(); thisLayerRoot.Nodes.Add(thisFieldRoot); DebugUtil.WriteLine(" " + "NameRef: " + fieldDefn.GetNameRef() + ": " + "Type: " + fieldDefn.GetFieldType() + "Type Name: " + fieldDefn.GetFieldTypeName(fieldDefn.GetFieldType()) + " (" + fieldDefn.GetWidth() + "." + fieldDefn.GetPrecision() + ")"); } #endif /* -------------------------------------------------------------------- */ /* Reading the Features */ /* -------------------------------------------------------------------- */ // Get the FeatureDefn pointer for this layer featureDefn = thisLayer.GetLayerDefn(); // get the feature list for this layer feature = new Feature(featureDefn); while ((feature = thisLayer.GetNextFeature()) != null) { // create the subtree and name it featureTree = new TreeNode(); // get the field name. Most lights have names as do some bouys, bridges and other landmarks. The featureNameList controls the fields // we look for names in. Most feature do NOT have names. fieldName = ""; foreach (string field in featureNameList) { if ((objIndex = featureDefn.GetFieldIndex(field)) >= 0) { // if the name is already found, do not reassign it if (fieldName == "") { fieldDefn = featureDefn.GetFieldDefn(objIndex); fieldName = DecodeField(feature, fieldDefn, objIndex); if (fieldName != null && fieldName != "") { featureTree.Name = fieldName; featureTree.Text = featureTree.Name; } } } } // if no name is found above, assign it "unnamed" unless the layer is DSID if (fieldName == "" & thisLayer.GetName() != "DSID") { fieldName = "Unnamed"; featureTree.Name = fieldName; featureTree.Text = featureTree.Name; } // DSID has to be handled differently. It has not displayable data and has it's own fieldlist if (thisLayer.GetName() == "DSID") { foreach (string field in DSIDList) { if ((objIndex = featureDefn.GetFieldIndex(field)) >= 0) { fieldDefn = featureDefn.GetFieldDefn(objIndex); fieldValue = DecodeField(feature, fieldDefn, objIndex); // field values are never 0 if (fieldValue != null && fieldValue != "") { TreeUtil.AddChildNode(parentLayerTree, field, fieldValue); } } } } else { // The fieldList contains the names of the fields are interested in. We do not want all fields as many of them are // irrelevant to diplaying the image such as the agency names and quality of the data, etc. foreach (string field in fieldList) { // check each feature for the key attributes and add them to the tree if they exist. if ((objIndex = featureDefn.GetFieldIndex(field)) >= 0) { if (feature.IsFieldSet(objIndex)) { fieldDefn = featureDefn.GetFieldDefn(objIndex); fieldValue = DecodeField(feature, fieldDefn, objIndex); // valid field values are never 0 or empty if (fieldValue != null && fieldValue != "") { TreeUtil.AddChildNode(featureTree, field, fieldValue); } } } } } // get the details of the fields. This is mostly diagnostic code, but it does populate the tree with positional information CreateTreeFields(ref featureTree, feature, featureDefn); // add the subtree parentLayerTree.Nodes.Add(featureTree); feature.Dispose(); } }
/* -------------------------------------------------------------------- */ /* Reading the Fields in this Feature */ /* -------------------------------------------------------------------- */ public static void CreateTreeFields(ref TreeNode thisFeatureTree, Feature feature, FeatureDefn featureDefn) { // field definition as we iterate through the fields FieldDefn iFieldDefn; int nameIndex; int objlIndex; string nameString; string objlString; // To get the name and the S-57 Type code (OBJL), we have to look forward into the fields. This piece of code // is mostly here to show how that is done as will need this when rendering these objects. You could easily add // shapes or color, but it is not necessary here. The name and the code is nice for the debug file though so we can // see what each feature is. // OBJL field should always exist - the exception are the meta data fields such as DSID which has no code. objlIndex = featureDefn.GetFieldIndex("OBJL"); if (objlIndex > 0) { objlString = DecodeField(feature, featureDefn.GetFieldDefn(objlIndex), objlIndex); } else { objlString = "No Code"; } // name field may not exist. we could get either the info or text description if they exist nameIndex = featureDefn.GetFieldIndex("OBJNAM"); if (nameIndex > 0) { nameString = DecodeField(feature, featureDefn.GetFieldDefn(nameIndex), nameIndex); } else { nameString = "Not Named"; } DebugUtil.WriteLine(); DebugUtil.WriteLine(string.Format(" *** Feature: {0}, Name: {1}, S-57 Code: {2}", featureDefn.GetName(), nameString, objlString)); DebugUtil.WriteLine(); // get the styles, if any if (feature.GetStyleString() != null) { DebugUtil.WriteLine(" Style = " + feature.GetStyleString()); } // this gets the sub-geometries. not all features have sub-geometries Geometry geom = feature.GetGeometryRef(); if (geom != null) { DebugUtil.WriteLine(" Geometry Name: " + geom.GetGeometryName() + " Sub-geometry Count: " + geom.GetGeometryCount()); Geometry sub_geom; for (int i = 0; i < geom.GetGeometryCount(); i++) { sub_geom = geom.GetGeometryRef(i); if (sub_geom != null) { string subGeoString; DebugUtil.Write(" sub-geometry " + i + ": "); switch (sub_geom.GetGeometryType()) { case wkbGeometryType.wkbLineString: case wkbGeometryType.wkbPoint25D: sub_geom.ExportToWkt(out subGeoString); DebugUtil.WriteLine(subGeoString); TreeUtil.AddChildNode(thisFeatureTree, subGeoString); break; default: DebugUtil.WriteLine("Unhandled subgeometry type: " + sub_geom.GetGeometryType()); TreeUtil.AddChildNode(thisFeatureTree, "Unhandled sub-geomtry type", sub_geom.GetGeometryType().ToString()); break; } } } // a bit confusing, but if it has no sub geometries, use the base geometry. mostly applies to the type POINT if (geom.GetGeometryCount() == 0) { string geom_wkt; geom.ExportToWkt(out geom_wkt); DebugUtil.WriteLine(" geom_wkt: " + geom_wkt); TreeUtil.AddChildNode(thisFeatureTree, geom_wkt); } } // if geo != null for (int iField = 0; iField < feature.GetFieldCount(); iField++) { iFieldDefn = featureDefn.GetFieldDefn(iField); // not all fields have usable information, skip those that don't. if (feature.IsFieldSet(iField)) // IsFieldSet is a handy way to see if the field has any actual information { DebugUtil.Write(" "); DebugUtil.Write("Field Name: " + iFieldDefn.GetName() + ", "); DebugUtil.Write("Type Name: " + iFieldDefn.GetFieldTypeName(iFieldDefn.GetFieldType()) + ", "); DebugUtil.Write("Field Type: " + iFieldDefn.GetFieldType() + ", "); DebugUtil.Write("Value: " + DecodeField(feature, iFieldDefn, iField)); DebugUtil.WriteLine(); } // if isField } }
/// <summary> /// Iterates through the layers of the map and builds a tree based on the layer information /// </summary> /// <param name="ds"></param> /// <returns>"TreeNode"</returns> /// public static TreeNode CreateTree() { DebugUtil.WriteLine(); DebugUtil.WriteLine("*******************************************************************************************************"); DebugUtil.WriteLine("**** Building Tree ****"); DebugUtil.WriteLine("*******************************************************************************************************"); DebugUtil.WriteLine(); TreeNode topNode = new TreeNode(); TreeNode metaTree = new TreeNode(); Layer layer; string srs_wkt; Envelope thisEnvelope = new Envelope(); string coordinateString; // add the name of the chart as the name of this root topNode.Text = Path.GetFileName(ds.name); topNode.Name = Path.GetFileName(ds.name); // Meta Tree metaTree.Text = "Meta Data"; metaTree.Name = "Meta Data"; // get layer 0 (should be "DSID) for the meta data layer = ds.GetLayerByIndex(0); /* -------------------------------------------------------------------- */ /* Get the spatial reference. It is consistent for the entire map so we*/ /* only need to do it once. */ /* -------------------------------------------------------------------- */ OSGeo.OSR.SpatialReference sr = layer.GetSpatialRef(); // this should not be null if (sr != null) { sr.ExportToPrettyWkt(out srs_wkt, 1); TreeUtil.AddChildNode(metaTree, "Spatial Reference", srs_wkt); DebugUtil.WriteLine("Spatial Reference: " + srs_wkt); } else { TreeUtil.AddChildNode(metaTree, "Spatial Reference", "Spatial Reference Uknown"); srs_wkt = "SRS: Unknown."; } // get Envelope for this layer layer.GetExtent(thisEnvelope, 1); // Get the Extents for the map. Again, they are consistent for the entire map, so we only need to do this once. if (thisEnvelope != null) { coordinateString = String.Format("MaxX = {0}, MaxY = {1}, MinX = {2}, MinY = {3}.", thisEnvelope.MaxX, thisEnvelope.MaxY, +thisEnvelope.MinX, thisEnvelope.MinY); DebugUtil.WriteLine("Extents: " + coordinateString); TreeUtil.AddChildNode(metaTree, "Envelope: ", coordinateString); } // add metaTree to topNode topNode.Nodes.Add(metaTree); // go through all the layers starting at zero for (int i = 0; i < ds.GetLayerCount(); i++) { layer = ds.GetLayerByIndex(i); if (layer != null) { // most of the work is done here CreateTreeLayers(topNode, layer, i); } else { DebugUtil.WriteLine("*********** Critical Error *************"); DebugUtil.WriteLine("Layer: " + i + " is null and does not exist."); MessageBox.Show("Critical Error: " + "Layer: " + i + " is null and does not exist."); } } DebugUtil.WriteLine(" TopNode node count is " + topNode.Nodes.Count + "."); // save the tree to a file. this is controlled by the debug flags. note that the file can get very large TreeUtil.OpenPrintRecursive("TreeNode.txt"); TreeUtil.PrintRecursive(topNode); // close the debug files DebugUtil.Close(); TreeUtil.Close(); return(topNode); }
/// <summary> /// Render is where most of the work is done. It builds a list of graphics items to be displayed and calls the S-52 rendorer to actually display them. /// We could pass the layer, but that would mean that the S-52 code would have to decipher the layers. It seems easier just to build a list and let S-52 /// only take care of the colors, symbol, and tiling. /// /// The goal is to create one list for each layer in the S57 record and have S52 render that layer. /// /// S-52 will return a map of the collective layers to display. This can then either be displayed or tiled or both. /// </summary> /// <param name="angle"></param> /// <returns></returns> public static Map Render(DataSource ds) { // the the cursor to the little swirling circle Cursor.Current = Cursors.WaitCursor; S57Layer layerCollection = new S57Layer(); SharpMap.Data.FeatureDataSet fds = new FeatureDataSet(); VectorLayer vectorLayer; Map map = new Map(); int featureCount; //int iFeatureCount; int fieldIndex; string fieldValue; SharpMap.Data.Providers.Ogr dataProvider; //SharpMap.Layers.Layer thisLayer; OSGeo.OGR.Feature thisFeature; OSGeo.OGR.FeatureDefn featureDefn; OSGeo.OGR.FieldDefn fieldDefn; OSGeo.OGR.Layer thisLayer; Geometry geometry; Geometry sub_geometry; string WKTGeometry; DebugUtil.WriteLine("****************************************************************************"); DebugUtil.WriteLine("*** Render ***"); DebugUtil.WriteLine("****************************************************************************"); // get the datasource that is currently open // ds = S57.DataSource; // we are only displaying the layers that our config data says to. int count = S57.myS57Objects.GetCount(); for (int i = 0; i < count; i++) { if (myS57Objects.GetDisplayFlag(i)) { layerCollection.layerName = myS57Objects.S57ObjectsList[i].ObjectName; } } for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { thisLayer = DataSource.GetLayerByIndex(iLayer); DebugUtil.WriteLine("*** Layer = " + thisLayer.GetName() + "Layer Number: " + iLayer); featureCount = thisLayer.GetFeatureCount(0); // a value of zero will get current feature count. a value of 1 will force a feature count and is slow DebugUtil.WriteLine("*** Feature Count: " + featureCount); // FeatureDefn pointer featureDefn = thisLayer.GetLayerDefn(); DebugUtil.WriteLine("*** Feature Definition Name: " + featureDefn.GetName() + "Field Count: " + featureDefn.GetFieldCount()); // allocate a feature set for this layer based on featureDefn thisFeature = new Feature(featureDefn); DebugUtil.WriteLine("*** thisFeature Definition Reference: " + thisFeature.GetDefnRef()); // get a SharpMap dataprovider for this vector layer. this is needed before we // can render the file dataProvider = new SharpMap.Data.Providers.Ogr(S57.FileName, iLayer); // make sure the dataprovider is open if (!dataProvider.IsOpen) { dataProvider.Open(); } //featureCount = thisLayer.GetFeatureCount(0); //for (iFeatureCount = 0; iFeatureCount < featureCount; iFeatureCount++) // reset the current feature to 0 then read all the features thisLayer.ResetReading(); while ((thisFeature = thisLayer.GetNextFeature()) != null) { if (thisFeature == null) { MessageBox.Show("thisFeature is null and can not be processed."); System.Environment.Exit(-1); } DebugUtil.WriteLine("Field count from thisFeature: " + thisFeature.GetFieldCount().ToString()); // Get the fields we want using the fieldList. This avoids process fields that have nothing to do with display. foreach (string thisField in fieldList) { // check each feature for the key attributes and add them to the tree if they exist. if ((fieldIndex = thisFeature.GetFieldIndex(thisField)) >= 0) { DebugUtil.WriteLine("Field = " + thisField + ". Field Index = " + fieldIndex); fieldDefn = featureDefn.GetFieldDefn(fieldIndex); fieldValue = DecodeField(thisFeature, fieldDefn, fieldIndex); // valid field values are never 0 or empty if (fieldValue != null && fieldValue != "" && fieldValue != "0") { // this gets the sub-geometries. not all features have sub-geometries geometry = thisFeature.GetGeometryRef(); // only render things that actually have geometries if (geometry != null) { // a bit confusing, but if it has no sub geometries, use the base geometry. mostly applies to the type POINT if (geometry.GetGeometryCount() == 0) { geometry.ExportToWkt(out WKTGeometry); vectorLayer = new VectorLayer(thisLayer.GetName(), dataProvider); DebugUtil.WriteLine("Rendering: " + WKTGeometry); //vectorLayer = S52.Render(ref vectorLayer, dataProvider, thisFeature, fieldDefn, WKTGeometry); vectorLayer = S52.Render(thisLayer.GetName(), fds); map.Layers.Add(vectorLayer); //vectorLayer.Dispose(); } else { for (int i = 0; i < geometry.GetGeometryCount(); i++) { sub_geometry = geometry.GetGeometryRef(i); if (sub_geometry != null) { sub_geometry.ExportToWkt(out WKTGeometry); vectorLayer = new VectorLayer(thisLayer.GetName(), dataProvider); DebugUtil.WriteLine("Rendering: " + WKTGeometry); //vectorLayer = S52.Render(ref vectorLayer, dataProvider, thisFeature, fieldDefn, WKTGeometry); vectorLayer = S52.Render(thisLayer.GetName(), fds); map.Layers.Add(vectorLayer); //vectorLayer.Dispose(); } } } } } } } } // free the feature collection for this layer //thisFeature.Dispose(); } map.ZoomToExtents(); //Matrix mat = new Matrix(); //mat.RotateAt(angle, map.WorldToImage(map.Center)); //map.MapTransform = mat; // change back to the defaul cursor Cursor.Current = Cursors.Default; return(map); }