Subscribe to this thread
Home - General / All posts - split shapefile based on attributes
DaveW2 post(s)
#31-Aug-16 14:04

Hi All,

I am new to manifold, and cant seem to find a simple method to split a shapefile according to attributes. At present having to go into the table and complete manually.

any help greatly appreciated!

firsttube


1,439 post(s)
#31-Aug-16 14:28

Can you clarify what you mean by "split a shapefile"?

I assume you mean you want to cut some objects out of a Drawing and paste them to a new drawing based on a certain value in a column in the Drawing's table.

You can use the selection bar to perform a selection on a particular column in the drawing's table. You could also create a Query and run the query to perform the selection. Then open the drawing and choose Edit > Cut. Then right-click in the project pane and choose Paste As > Drawing.


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

DaveW2 post(s)
#31-Aug-16 14:44

Thanks firsttube.

Sorry but I am new to this so don't have the language down.

To explain through an example, I have a Drawing with the road network for a country, the attribute table split into types as National, Regional, secondary, tertiary etc. - in order to create a separate Drawing for each type of road I now copy each type and create a new Drawing. This can get tedious if there are 20 road types, and I have many other Shapefiles which need this split.

Appreciate any help, thanks!!

firsttube


1,439 post(s)
#31-Aug-16 17:28

My next question is: why do you need a separate drawing for each type of road? Are you wanting to theme the different road types in a map or layout? If so, you can use a Theme component for this.

In Manifold you can create queries and then link a drawing to a query to create a "new" drawing.


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

tonyw
547 post(s)
#31-Aug-16 17:28

Hi DaveW

What is the end result or purpose of separating your data in separate drawings? Is it to give each road type a different line type or colour? If so, check out the topic "thematic format" topic in the manual. If you have a column named, say "road type" then you can assign different line types and colours to each road type. There are other ways of using thematic formatting too, say you want a map that only shows major routes, then you assign an invisible colour to the road types to hide. You can also save thematic formatting and re-apply it later for different themed maps (look for the disk icon and file folder icon in the thematic formatting dialog box).

[edit. FirstTube beat me to a posti]

firsttube


1,439 post(s)
#31-Aug-16 17:35

If you need separate drawings for each road type you could create a query for each type like this:

--sql

options coordsys("Roads" as component);

select * from [Roadswhere [Type] = "National"

Then you create a linked drawing by selecting File > Link > Drawing. Choose "This Project", click OK. Select "Table with geometry column" in the Type box. Choose the query in the Source box. If you used the SQL I posted then the Geometry box would be "Geom (I)". Click OK.

You'll see a new drawing created, and that drawing contains the result of the query, which in this case is all objects with the value "National" in the column "Type".


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

Shane3 post(s)
#13-Sep-16 09:42

Hi firsttube,

I am working with DaveW on this. First of all thanks heaps for the advice, I have managed after a few tries to replicate what you were suggesting and get it to work, very happy we managed to do this so THANKS!

A few questions have arise from the task which I would appreciate your comment on:

- If you are trying to split a drawing into multiple sub-components, is it possible to write one query which will split the drawing and create linked drawings of each of the constituent parts or do you have to create one query for each component?

- Considering we have created a linked drawing from the original, I assume that now if we change the original it will also change the linked drawing? I.e. if we delete a street

- Is it possible to select multiple values to paste into the same linked drawing? I.e. could we choose [Type] = "National" & "Secondary" if we want to group them together... not sure of the syntax required but the idea is there.

This is the query I ended up writing for Streets:

--sql

options coordsys("20160704_NGI_Cintsa_Roads(2006)_SQ" as component);

select * from [20160704_NGI_Cintsa_Roads(2006)_SQ] where [FEAT_TYPE] = "STREET"

And this one for Tracks:

--sql

options coordsys("20160704_NGI_Cintsa_Roads(2006)_SQ" as component);

select * from [20160704_NGI_Cintsa_Roads(2006)_SQ] where [FEAT_TYPE] = "TRACK FOOTPATH"

firsttube


1,439 post(s)
#13-Sep-16 20:01

I think the best way to do what you are trying to do is one query per part. If there are too many sub-components to do manually you could write a script to create the queries.

The linked drawings will update when you open the manifold project. Or you can right-click on each linked drawing and choose "Refresh Data" and this will update the linked drawing. You could also write a script to run through and update all linked drawings.

First, you don't "paste" things into a linked drawing. The objects in a linked drawing are coming from another drawing that the query is acting on.

Second, yes you can write a query like this and link a drawing to it:

--sql

options coordsys("Roads" as component);

select * from [Roads] where [Type] = "National"

or [Type] = "Secondary"


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

tjhb

8,950 post(s)
#13-Sep-16 21:54

If you use my script (see link below), either standalone or as an add-in, it does all that for you (writes all the queries, makes the target drawings, and uses SQL to fill them).

There's nothing wrong with doing all that manually if you like, but a script does save time.

It just asks for a source column to split by (it guesses the first user column).

artlembo

3,117 post(s)
#31-Aug-16 17:48

there are about a hundred ways to do this, but I just did this one quick and dirty. Let's assume you have a drawing named "D", with a field called "tp" that has your road types:

Sub Main

 Set roads = document.ComponentSet("D")

 Set qry = document.NewQuery("Q",true)

 Set qry2 = document.NewQuery("Q2",true)

 qry.text = "select tp from D group by tp"

 for each rec in qry.Table.RecordSet

    thetype = rec.Data("tp")

    Set newdrw = document.newdrawing(thetype,roads.CoordinateSystem,true)

    qry2.text = "update D SET [Selection (I)] = true WHERE tp = " & chr(34) & thetype & chr(34)

    qry2.runEx true

    roads.copy(true)

    newdrw.paste

    roads.selectnone

 next

 document.ComponentSet.Remove("Q")

 document.ComponentSet.Remove("Q2")

End Sub

the above script will get all the unique names in the column tp, then for each of those names, it will issue a query to select the records with only that unique name by updating the table selection. Then, it copies the records and pastes it into the new table.

It's a pretty short script, but really useful - it only took about 5 minutes to write it (I hadn't written Manifold VBScript for awhile). If you want to learn how to script like this, check out the Scripting Manifold with VBScript course.

artlembo

3,117 post(s)
#31-Aug-16 19:05

here is a quick video showing it in action (not sure if the video tags work in the forum).

Attachments:
split.mp4

tjhb

8,950 post(s)
#31-Aug-16 22:52

there are about a hundred ways to do this

Amen! Here's an old one, which I use as an add-in.

It's VBScript, but uses SQL for the data copying, usually faster than copy and paste.

To use it as an add-in, copy both files to the Manifold Config folder (e.g. C:\Program Files\Manifold System\Config, administrative permissions required) and relaunch Manifold. It will appear under Tools > Add-ins as "Drawing - Split by attribute".

artlembo

3,117 post(s)
#31-Aug-16 23:02

This would be fun to test out. That plug-in is a lot of code, and I think the system copy and paste functions are much better than the row by row insertions. Also, the copy and paste handles all the columns automatically.

firsttube


1,439 post(s)
#01-Sep-16 13:45

I have encountered issues with using the system clipboard for copy/paste objects. I've found that the system clipboard could be used simultaneously by other applications at the same time the Manifold script is using it, so there could be conflicts. I've started to use SQL more and more for these types of tasks to avoid this, especially if the script is to be run on another users' system and it has to run "flawlessly".


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

artlembo

3,117 post(s)
#01-Sep-16 14:01

that makes a lot of sense in terms of a volatile system where lots of things are happening. For personal use, I think this should work fine, but in a production environment, perhaps not - especially if you have other things running in the background that use the clipboard.

artlembo

3,117 post(s)
#01-Sep-16 18:48

in case you want a line-by-line description of what this query does, I wrote about it on my blog here

Manifold User Community Use Agreement Copyright (C) 2007-2019 Manifold Software Limited. All rights reserved.