Beispiel #1
0
        // copy selected feature to new layer
        private void toLayerButton_Click(object sender, EventArgs e)
        {
            toolBuilder.addHeader("Export selection");
            // textbox for new layer name
            TextBox textbox = toolBuilder.addTextboxWithCaption("Layer name:");
            Label errorLabel = toolBuilder.addErrorLabel();
            // button for performing copy
            Button selectButton = toolBuilder.addButton("Copy selection", (Layer l) =>
            {
                if (textbox.Text.Length == 0)
                {
                    errorLabel.Text = "Provide a name";
                    return;
                }

                Layer newl = new Layer(textbox.Text);
                // copy attributes
                newl.DataTable = l.DataTable;
                // copy features
                foreach (Feature f in l.Selected)
                    newl.addFeature(new Feature((Geometry)f.Geometry.Clone(), f.ID));
                newl.calculateBoundingBox();
                newl.createQuadTree();
                Layers.Insert(0, newl);
                // select newly made layer
                layerList.SelectedItem = newl;
            });

            // change default new layer name when new layer is selected
            toolBuilder.resetAction = (Layer l) =>
            {
                textbox.Text = (l == null) ? "" : l.Name + "_copy";
            };
            toolBuilder.reset();
        }
Beispiel #2
0
        // calculate intersection of layers
        private void intersectButton_Click(object sender, EventArgs e)
        {
            toolBuilder.addHeader("Intersect");
            // dropdown for selecting other layer
            ComboBox layerSelect = toolBuilder.addLayerSelect("Intersect with:");
            // textbox for new layer name
            TextBox textbox = toolBuilder.addTextboxWithCaption("New layername:");
            // laber for errors
            Label errorLabel = toolBuilder.addErrorLabel();
            //button for performing intersection
            Button button = toolBuilder.addButton("Intersect", (Layer l) =>
            {
                // new layer name not given
                if (textbox.Text.Length == 0)
                {
                    toolBuilder.setError("Provide name");
                    return;
                }
                Layer intersectLayer = (Layer)layerSelect.SelectedItem;
                Layer newLayer = new Layer(textbox.Text);

                // if both layers have attributes
                if (l.DataTable != null && intersectLayer.DataTable != null)
                {
                    // merge attributes, columnName collisions may be overwritten
                    DataTable a = l.DataTable.Clone();
                    newLayer.DataTable = intersectLayer.DataTable.Clone();
                    newLayer.DataTable.Merge(a, true, MissingSchemaAction.Add);
                }
                // if only one layer has attributes
                else if (l.DataTable != null && intersectLayer.DataTable == null)
                {
                    newLayer.DataTable = l.DataTable.Clone();
                }
                // if only the other layer has attributes
                else if (l.DataTable == null && intersectLayer.DataTable != null)
                {
                    newLayer.DataTable = intersectLayer.DataTable.Clone();
                }

                // init progress bar
                progressLabel.Text = "Intersection";
                progressBar.Minimum = 0;
                progressBar.Maximum = l.Features.Values.Count;

                // background worker for running in another thread
                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerReportsProgress = true;
                bw.DoWork += (object wsender, DoWorkEventArgs we) =>
                {
                    // loop through all features
                    for (int i = 0; i < l.Features.Count; i++ )
                    {
                        Feature f = l.Features.Values.ElementAt(i);
                        bw.ReportProgress(i);
                        // get intersecting features
                        var intersections = intersectLayer.getWithin(f.Geometry);
                        foreach (Feature intersect in intersections)
                        {
                            DataRow arow = l.getRow(f);
                            DataRow brow = intersectLayer.getRow(intersect);

                            // calculate intersection
                            Feature result = new Feature(f.Geometry.Intersection(intersect.Geometry));
                            int id = newLayer.addFeature(result);

                            // merge attributes
                            if (newLayer.DataTable != null)
                            {
                                DataRow dr = newLayer.DataTable.NewRow();
                                if (arow != null)
                                    foreach (DataColumn dc in arow.Table.Columns)
                                        dr[dc.ColumnName] = arow[dc.ColumnName];
                                if (brow != null)
                                    foreach (DataColumn dc in brow.Table.Columns)
                                        dr[dc.ColumnName] = brow[dc.ColumnName];
                                dr["sgis_id"] = id;
                                newLayer.DataTable.Rows.Add(dr);
                            }
                        }
                    }
                };
                bw.RunWorkerCompleted += (object wsender, RunWorkerCompletedEventArgs we) =>
                {
                    // reset progress bar
                    progressBar.Value = 0;
                    progressLabel.Text = "";

                    // finalise new layer
                    newLayer.calculateBoundingBox();
                    newLayer.createQuadTree();
                    Layers.Insert(0, newLayer);
                    redraw();
                };
                bw.ProgressChanged += (object wsender, ProgressChangedEventArgs we) =>
                {
                    // update progress bar
                    progressBar.Value = we.ProgressPercentage;
                };
                bw.RunWorkerAsync();
            });
            // reset new layer name
            toolBuilder.resetAction += (Layer l) =>
            {
                textbox.Text = (l == null) ? "" : l.Name + "_intersect";
            };
            toolBuilder.reset();
        }
Beispiel #3
0
        // buffer layer
        private void bufferButton_Click(object sender, EventArgs e)
        {
            toolBuilder.addHeader("Buffer");

            // textbox for buffer distance
            TextBox distBox = toolBuilder.addTextboxWithCaption("Distance (m):");
            // textbox for new layername
            TextBox nameBox = toolBuilder.addTextboxWithCaption("New layername:");
            // label for errors
            Label errorLabel = toolBuilder.addErrorLabel();

            // button for performing buffer
            Button selectButton = toolBuilder.addButton("Buffer", (Layer l) =>
            {
                double dist = 0;
                // buffer does not work on lat-long projections
                if (SRS.IsLatLong)
                {
                    toolBuilder.setError("Incompatible SRS");
                    return;
                }
                // distance must be a number
                if (!double.TryParse(distBox.Text, out dist))
                {
                    toolBuilder.setError("Not a number");
                    return;
                }
                // user must give new layer name
                if (nameBox.Text.Length == 0)
                {
                    toolBuilder.setError("Provide a name");
                    return;
                }

                // create new layer
                Layer newl = new Layer(nameBox.Text);
                newl.DataTable = l.DataTable;

                List<Feature> flist = l.Features.Values.ToList();

                // initialise progress bar
                progressLabel.Text = "Buffering";
                progressBar.Minimum = 0;
                progressBar.Maximum = flist.Count;

                // threadsafe list of new features
                ConcurrentBag<Feature> newFeatures = new ConcurrentBag<Feature>();

                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerReportsProgress = true;

                // perform buffering in other thread
                bw.DoWork += (object wsender, DoWorkEventArgs we) =>
                {
                    using (var finished = new CountdownEvent(1))
                    {
                        // for each feature
                        for (int i = 0; i < flist.Count; i++)
                        {
                            // add the task to buffer a feature to a thread pool
                            finished.AddCount();
                            Feature capture = flist[i];
                            ThreadPool.QueueUserWorkItem((state) =>
                            {
                                // get feature
                                Feature f = capture;
                                // add buffered feature
                                newFeatures.Add(new Feature(f.Geometry.Buffer(dist), f.ID));
                                bw.ReportProgress(i);
                                finished.Signal();
                            }, null);
                        }
                        finished.Signal();
                        finished.Wait();
                    }
                    bw.ReportProgress(-1);
                    // add all buffered features to layer
                    foreach(Feature f in newFeatures)
                    {
                        newl.addFeature(f);
                        bw.ReportProgress(1);
                    }
                    newl.calculateBoundingBox();
                    newl.createQuadTree();
                };
                bw.RunWorkerCompleted += (object wsender, RunWorkerCompletedEventArgs we) =>
                {
                    // reset progress bar
                    progressBar.Value = 0;
                    progressLabel.Text = "";

                    // add and zoom newly made layer
                    Layers.Insert(0, newl);
                    layerList.SelectedItem = newl;
                };
                bw.ProgressChanged += (object wsender, ProgressChangedEventArgs we) =>
                {
                    // update progress bar and progress label
                    if (we.ProgressPercentage == -1){
                        progressBar.Value = 0;
                        progressLabel.Text = "Creating spatial index";
                    }
                    else
                        progressBar.Value += 1;
                };
                bw.RunWorkerAsync();
            });

            toolBuilder.resetAction = (Layer l) =>
            {
                if (SRS.IsLatLong)
                    toolBuilder.setError("Incompatible SRS");
                nameBox.Text = (l == null) ? "" : l.Name + "_buffer";
            };

            toolBuilder.reset();
        }
Beispiel #4
0
        private void diffButton_Click(object sender, EventArgs e)
        {
            toolBuilder.addHeader("Difference");
            // dropdown for selecting other layer
            ComboBox layerSelect = toolBuilder.addLayerSelect("Layer to subtract:");
            // textbox for new layer name
            TextBox textbox = toolBuilder.addTextboxWithCaption("New layername:");
            // label for errors
            Label errorLabel = toolBuilder.addErrorLabel();
            // button for performing subtraction
            Button button = toolBuilder.addButton("Subtract", (Layer l) =>
            {
                // no new layer name is given
                if (textbox.Text.Length == 0)
                {
                    toolBuilder.setError("Provide name");
                    return;
                }
                // layers must have the same type of shapes
                Layer unionLayer = (Layer)layerSelect.SelectedItem;
                if (l.shapetype != unionLayer.shapetype)
                {
                    toolBuilder.setError("Incompatible types");
                    return;
                }
                Layer newLayer = new Layer(textbox.Text);
                newLayer.DataTable = l.DataTable;

                // init progress bar
                progressLabel.Text = "Subtracting";
                progressBar.Minimum = 0;
                progressBar.Maximum = l.Features.Values.Count;

                // background worker for running operation in another thread
                BackgroundWorker bw = new BackgroundWorker();
                bw.WorkerReportsProgress = true;
                bw.DoWork += (object wsender, DoWorkEventArgs we) =>
                {
                    // threadsafe list for storing new features
                    ConcurrentBag<Feature> newFeatures = new ConcurrentBag<Feature>();
                    using (var finished = new CountdownEvent(1))
                    {
                        foreach (Feature f in l.Features.Values)
                        {
                            finished.AddCount();
                            Feature capt = f;
                            // in each thread
                            ThreadPool.QueueUserWorkItem((state) =>
                            {
                                // clone feature
                                Feature newf = new Feature((IGeometry)capt.Geometry.Clone(), capt.ID);
                                // get intersecting features
                                var intersects = unionLayer.getWithin(capt.Geometry);
                                // subtract intersecting features
                                foreach (Feature intersect in intersects)
                                    newf.Geometry = newf.Geometry.Difference(intersect.Geometry);

                                // if there is something left of the original feature
                                if (!newf.Geometry.IsEmpty) // add it to new feature list
                                    newFeatures.Add(newf);
                                bw.ReportProgress(1);
                                finished.Signal();
                            }, null);
                        }
                        finished.Signal();
                        finished.Wait();
                    }
                    bw.ReportProgress(-newFeatures.Count);
                    // add all processed features to new layer
                    foreach (Feature f in newFeatures)
                    {
                        newLayer.addFeature(f);
                        bw.ReportProgress(1);
                    }
                };
                bw.RunWorkerCompleted += (object wsender, RunWorkerCompletedEventArgs we) =>
                {
                    // reset progressbar
                    progressBar.Value = 0;
                    progressLabel.Text = "";

                    // create quad tree and insert new layer
                    newLayer.calculateBoundingBox();
                    newLayer.createQuadTree();
                    Layers.Insert(0, newLayer);

                    redraw();
                };
                bw.ProgressChanged += (object wsender, ProgressChangedEventArgs we) =>
                {
                    // update progress bar
                    if (we.ProgressPercentage < 0)
                    {
                        progressBar.Value = 0;
                        progressBar.Maximum = -we.ProgressPercentage;
                        progressLabel.Text = "Creating spatial index";
                    }
                    else
                        progressBar.Value += we.ProgressPercentage;
                };
                bw.RunWorkerAsync();
            });
            // reset new layer name when selected layer changes
            toolBuilder.resetAction += (Layer l) =>
            {
                textbox.Text = (l == null) ? "" : l.Name + "_diff";
            };
            toolBuilder.reset();
        }