FromXml() public method

public FromXml ( System.Xml.Linq.XElement res, string directoryName ) : void
res System.Xml.Linq.XElement
directoryName string
return void
Exemplo n.º 1
0
        public static void Merge(PoiService mainDataService, string mainKey, PoiService secondaryDataService,
            string secKey,
            bool includeSecondaryPois,
            bool excludeNonExistentSecondaryPois,
            bool includeSecondaryColumns,
            bool overwriteDuplicateLabels, bool stopOnFirstHit, bool includeMetaData, FileLocation destination = null,
            TextBox txtMergeDebugOutput = null) {
            if (txtMergeDebugOutput != null)
                txtMergeDebugOutput.Text = "Merging files on [" + mainKey + " = " + secKey + "]";

            // Determine whether to use well-known text.
            var mainPoiType = mainDataService.PoITypes.FirstOrDefault();
            if (mainPoiType == null) {
                mainPoiType                = new PoI {
                    Name                   = "Default",
                    ContentId              = "Default",
                    Service                = mainDataService,
                    Style                  = new PoIStyle {
                        Name               = "default",
                        FillColor          = Colors.Transparent,
                        StrokeColor        = Color.FromArgb(255, 128, 128, 128),
                        CallOutOrientation = CallOutOrientation.Right,
                        FillOpacity        = 0.3,
                        TitleMode          = TitleModes.Bottom,
                        NameLabel          = "Name",
                        DrawingMode        = DrawingModes.Image,
                        StrokeWidth        = 2,
                        IconWidth          = 24,
                        IconHeight         = 24,
                        Icon               = "images/missing.png",
                        CallOutFillColor   = Colors.White,
                        CallOutForeground  = Colors.Black,
                        TapMode            = TapMode.CallOut
                    },
                    Id                     = Guid.NewGuid(),
                    DrawingMode            = DrawingModes.Image,
                    MetaInfo               = new List<MetaInfo>()
                };
                mainDataService.PoITypes.Add(mainPoiType);
            }

            if (mainPoiType != null && string.IsNullOrEmpty(mainPoiType.ContentId)) mainPoiType.ContentId = "Default";
            BaseContent secondaryPoiType = null;
            if (secondaryDataService.PoITypes != null && secondaryDataService.PoITypes.Any()) {
                secondaryPoiType = secondaryDataService.PoITypes.FirstOrDefault();
            }
            ;
            bool useWKT = mainPoiType != null && mainPoiType.Style != null && mainPoiType.Style.Name == "WKT";
            useWKT = (useWKT || secondaryPoiType != null && secondaryPoiType.Style != null) &&
                     secondaryPoiType.Style.Name == "WKT" && includeSecondaryColumns;
            if (useWKT) {
                if (mainPoiType != null) {
                    mainPoiType.ContentId = "WKT"; // We directly set the main PoI's "PoiId" to WKT.                    
                }
                mainDataService.StaticService = true; // Make sure we save the file as static.
                if (txtMergeDebugOutput != null)
                    txtMergeDebugOutput.AppendText(
                        "\nOne of the files uses well-known text; the output will be a static layer.");
            }

            // Merge the meta info. 
            if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nMerging meta info.");
            if (secondaryPoiType != null && secondaryPoiType.MetaInfo.Count == 0) {
                //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nSecondary file has no meta info; nothing to merge.");
            }
            if (secondaryPoiType != null && includeSecondaryColumns)
                foreach (MetaInfo secMetaInfo in secondaryPoiType.MetaInfo) {
                    string secMetaInfoLabel = secMetaInfo.Label;
                    bool doAdd = true;
                    if (secMetaInfoLabel == secKey) {
                        //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nLabel " + secMetaInfo.Label + " is the one we merge on, so we skip it.");
                        doAdd = false;
                    }
                    if (doAdd) {
                        if (mainPoiType != null) {
                            if (mainPoiType.MetaInfo.Any(mainMetaInfo => mainMetaInfo.Label == secMetaInfoLabel)) {
                                doAdd = false; // label already there.
                            }
                        }
                    }
                    if (!doAdd) continue;
                    if (mainPoiType != null)
                        mainPoiType.MetaInfo.Add(secMetaInfo);
                    //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nInserted meta-info from secondary file into main file: " + secMetaInfo.Label + ".");
                }

            // Merge the Style info. If the right file has WKT, set the drawing mode to MultiPolygon.
            // TODO For now we completely ignore some important aspects of poitypes:
            // 1. Multiple PoITypes.
            // 2. Different PoiId attributes.
            if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nMerging styles.");
            if ((secondaryPoiType != null && secondaryPoiType.Style != null && (mainPoiType.Style == null))) {
                // We need to overwrite, or the main does not have something yet.                
                mainPoiType.Style = secondaryPoiType.Style;
                //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nInserted style from secondary file into main file.");
            }
            else {
                //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nMain file already has a style definition.");
            }
            if (useWKT) {
                mainPoiType.Style.DrawingMode = DrawingModes.MultiPolygon;
//                if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText(
//                    "\nEnsuring main file uses drawing mode 'multi polygon' given the fact that well-known text is used.");
            }

            // Remember which PoIs were found in the main as well as secondary file.
            HashSet<BaseContent> unvisitedMainPois = new HashSet<BaseContent>();
            foreach (var poI in mainDataService.PoIs) {
                unvisitedMainPois.Add(poI);
            }

            // Merge data.
            if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n\nMerging data.");
            foreach (var secPoi in secondaryDataService.PoIs) {
                if (!secPoi.Labels.ContainsKey(secKey)) {
//                    if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n" + secPoi.Id + " does not have label " + secKey +
//                                                   " and will be skipped.");
                    continue;
                }
                var mainPoiFound = false;
                //var mainPoi = mainDataService.PoIs.FirstOrDefault(p => p.Labels.ContainsKey(mainKey) 
                //    && string.Equals(p.Labels[mainKey], secPoi.Labels[secKey], StringComparison.InvariantCultureIgnoreCase));
                foreach (var mainPoi in mainDataService.PoIs.Where(mainPoi =>
                    mainPoi.Labels.ContainsKey(mainKey)
                    &&
                    string.Equals(mainPoi.Labels[mainKey], secPoi.Labels[secKey],
                        StringComparison.InvariantCultureIgnoreCase)))
                    if (mainPoi != null) {
                        mainPoiFound = true;
                        if (mainPoi.PoiType == null) {
                            mainPoi.PoiType = mainPoiType;
                            mainPoi.ContentId = mainPoiType.ContentId;
                        }
                        unvisitedMainPois.Remove(mainPoi); // We visited this PoI! :)

                        if (!includeSecondaryColumns)
                            continue; // Do not copy information from the secondary to the first.
                        //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nAdding new data to " + mainPoi.Labels[mainKey] + ".");
                        //GetShortFriendlyName(mainPoi.Name) + "." + mainKey + " = " + GetShortFriendlyName(secPoi.Name) + "." + secKey + "] = " + );

                        // Merge the labels part.
                        if (overwriteDuplicateLabels) {
                            //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nCopying label/values with overwrite: ");
                            foreach (var label in secPoi.Labels) {
                                if (label.Key != secKey) {
                                    //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n->" + label.Key + "=" + label.Value + ", ");
                                    mainPoi.Labels[label.Key] = label.Value;
                                }
                            }
                        }
                        else {
                            //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nCopying label/values without overwrite: ");
                            foreach (var label in secPoi.Labels.Where(l => l.Key != secKey)) {
                                string value;
                                if (mainPoi.Labels.TryGetValue(label.Key, out value)) {
                                    //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n->" + label.Key + " skipped (value already set to " + value + "), ");
                                    continue;
                                }
                                //if (label.Key == secKey)
                                //{
                                //    //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n->" + label.Key + " is the label on which we merge; skipped (value " + mainPoi.Labels[mainKey] + "), ");
                                //    continue;
                                //}
                                //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n->Setting " + label.Key + " to " + label.Value);
                                mainPoi.Labels[label.Key] = label.Value;
                            }
                        }

                        // Also merge WKT information there may be.
                        if (useWKT) {
                            mainPoi.PoiTypeId = "WKT";
                        }
                        if (!string.IsNullOrWhiteSpace(secPoi.WktText)) {
                            if (overwriteDuplicateLabels || string.IsNullOrWhiteSpace(mainPoi.WktText)) {
                                //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nAlso merged well-known text elements.");
                                mainPoi.WktText = secPoi.WktText;
                            }
                        }

                        // Stop if needed.
                        if (!stopOnFirstHit) continue;
                        if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nStopping on first hit!");
                        break;

                        // And that's it.
                        //if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\n");
                    }

                if (mainPoiFound) continue;
                if (includeSecondaryPois) {
                    var copyPoI = new PoI();
                    copyPoI.FromXml(secPoi.ToXml());
                    if (useWKT) {
                        copyPoI.PoiTypeId = "WKT";
                    }
                    else {
                        copyPoI.PoiType = mainPoiType;
                        copyPoI.PoiTypeId = mainPoiType.PoiId;
                    }
                    copyPoI.Labels[mainKey] = copyPoI.Labels[secKey]; // Rename the merge label.
                    copyPoI.Labels.Remove(secKey);
                    mainDataService.PoIs.Add(copyPoI);
                    if (txtMergeDebugOutput != null)
                        txtMergeDebugOutput.AppendText("\nMain file does not have PoI with label " + mainKey +
                                                       " set to " + secPoi.Labels[secKey] +
                                                       ", including PoI from secondary file.");
                }
                else {
                    if (txtMergeDebugOutput != null)
                        txtMergeDebugOutput.AppendText("\nMain file does not have PoI with label " + mainKey +
                                                       " set to " + secPoi.Labels[secKey] +
                                                       " and will be skipped.");
                }
            }

            // Report on unvisited PoIs in main file.
            // Remove any PoIs in the main file that are not in the secondary file (if the user selected this option).
            if (txtMergeDebugOutput != null) {
                if (unvisitedMainPois.Any()) {
                    if (txtMergeDebugOutput != null)
                        txtMergeDebugOutput.AppendText(
                            "\nSome PoIs in the main file were not matched with a PoI in the secondary file.");
                    if (excludeNonExistentSecondaryPois && txtMergeDebugOutput != null)
                        txtMergeDebugOutput.AppendText(" These PoIs will be removed from the main file.");
                }
                foreach (BaseContent unvisitedMainPoi in unvisitedMainPois) {
                    if (txtMergeDebugOutput != null) {
                        string unvisitedMainPoiValue;
                        bool found = unvisitedMainPoi.Labels.TryGetValue(mainKey, out unvisitedMainPoiValue);
                        if (!found) {
                            unvisitedMainPoiValue = "UNDEFINED";
                        }
                        txtMergeDebugOutput.AppendText("\n" + unvisitedMainPoi + ", " + mainKey + " = " +
                                                       unvisitedMainPoiValue + ".");
                    }
                }
                if (excludeNonExistentSecondaryPois) {
                    // Annoyingly, calling "remove" on a ContentList throws an exception.
                    // Therefore, we construct a new list of PoIs that should be kept, instead of removing the PoIs we should remove.
                    ContentList newMainPoIs = new ContentList();
                    foreach (BaseContent poI in mainDataService.PoIs.Where(poI => !unvisitedMainPois.Contains(poI))) {
                        newMainPoIs.Add(poI);
                    }
                    mainDataService.PoIs = newMainPoIs;
                }
            }

            // We are done.
            if (txtMergeDebugOutput != null) txtMergeDebugOutput.AppendText("\nMerge completed!");

            if (destination == null) {
                mainDataService.SaveXml();
            }
            else {
                PoiServiceExporters.Instance.Export(mainDataService, destination, includeMetaData);
            }
        }
Exemplo n.º 2
0
 private static ContentList ClonePoiTypes(PoiService source, string shapeIdLabel = null)
 {
     var clonedPoiTypes = new ContentList();
     // Add all other PoI types.
     foreach (var baseContent in source.PoITypes)
     {
         var clone = new PoI(); // Important that this is a PoI! Otherwise we have a casting problem elsewhere.
         clone.FromXml(baseContent.ToXml()); // Deep clone.
         // Add a MetaInfo for the counter.
         if (clone.MetaInfo == null)
         {
             clone.MetaInfo = new List<MetaInfo>();
         }
         clone.MetaInfo.Add(new MetaInfo()
         {
             Label       = AggregationCountLabel,
             Description = "The number of features belonging to this aggregation",
             IsEditable  = false,
             Type        = MetaTypes.number
         });
         if (shapeIdLabel != null) clone.MetaInfo.Add(new MetaInfo()
         {
             Label      = "Shape_Name",
             IsEditable = false,
             Type       = MetaTypes.text
         });
         clonedPoiTypes.Add(clone);
     }
     return clonedPoiTypes;
 }