Essentially, what I'm trying to do is to load/draw a map from a Tiled map using Nick Gravelyn's TiledLib. The map is saved in Tiled's XML format. However, when I try loading the map with the line
TiledLib.Map map = Content.Load<TiledLib.Map>("Maps/Map1");
it throws an ArgumentException. The whole thing renders like this in Tiled itself:
The map's XML source looks like this (not posted directly onto StackOverflow for obvious size reasons).
It worked at first (with a pretty simple map using only one tileset) but when I edited it to include a bit more stuff then it suddenly started doing this. Could it be related to my usage of tile objects?
EDIT: I have been able to work out that using tile objects was not the culprit; this map structure still creates the same error.
you get an exception because you didn't name the objects in the map, this will cause ArgumentException in TiledLib. So, to solve this issue you need to go back to Tiled program, (re)edit this map, and select every object in the map and give it a name (not property but name) then export the map again and (re)import it into the game content. This should fix the problem.
BTW: I recommend using regular layer for collide check not object layer.
Like this: Make small png file with a transparent red rectangle tile in it in the same map tile dimensions, add new layer to the map, name it CollideLayer, and in this CollideLayer put that red rectangle tile where you want to be a collide, and then in the game code you can check to see if the CollideLayer cell is empty or not. I find this is simpler.
I',m guessing, but looking at your XML structure in the section, there are a lot of repeats of
<tile gid="0"/>
in the data element. There is no documentation or schema definition on the structure of this file on the official site, and the content pipeline source is not available. Also, the demo of TileLib comes with that section as
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAC2NmYGBgpjKmFkA2jxCNrg+bHD7z0PWSYx428wmZjW4+qf7Fxyc3PnDFJS3jdzCbx4QFg8QZScTUzmcgDACR4mfdwAMAAA==
I'm not sure if you have an option to include encryption or not. But, the "gid" (global id ??) attribute cannot be the same for every tile defined if that is what it is. If I was writing this engine, I would have some way to readily identify each basic defined tile. Like a primary key on a data table. Which has to be unique. That would be the "gid" attribute for me.
Since the exception does not give any information (which is stupid - who deploys public libraries like that??), the argument exception is either that your "gid" attribute value is already defined, or that you're missing the encryption attributes which it expects in the pipeline importer or processor.
Related
I'm trying to figure out how to access the filled regions created when an object is cut in plan or section. My aim is to write a tool that duplicates these regions in order to quickly create dual hatches in a view.
I'm unsure at the moment whether these regions are associated with the family instance itself, or the view, or the work plane, etc.I've poured through Revit Lookup but can't locate it.
There is some information here about creating new filled regions through
FilledRegion.Create(...)
But I'm more interested in accessing the ones already created in a view.
Any suggestions would be much appreciated.
The code snippet below would return Elements of all the FilledRegions of the current Document (doc) in a specified View (v). I hope that gets you going in the right direction.
FilteredElementCollector collector = FilteredElementCollector(doc,v.Id).OfClass(typeof(FilledRegion));
Sorry, I misunderstood what you were looking for.
You can get the CutPatternId of a Material, which would return the pattern you see when an element is cut. I don't have a code snippet for you, but, what you'd want is:
User selects the Element
API gets all the Materials of that Element
API returns all the CutPatternIds of those Materials
(FillPatternElement)
API returns all the FilledRegionType(s) with
the same FillPatternId (creating them is necessary)
API generates the FilledRegion using the correct FilledRegionType.
Item 5 is the trickiest part because I'm not sure how you could determine the boundary it's supposed to draw. #jeremy-tammik is super smart, and he's the author of the blog you referenced. Maybe he could fill in the gap on this part. Maybe there is something you could return from an "Intersect" method?
I have those two entities :
Color entity is mapped to a table of constant values that represent colors.
Code=1, Name="Red"
Code=2, Name="Blue"
And so on...
In Car entity, the Color property is of type int and has a foreign key constraint to the Code property in Color entity. I want to convert the Color property in Car to an Enum, but the Enum should get it's values from Color table.
The Enum could be updated in each build action or an "update model" action in the designer.
Can this functionality can be achieved ?
" but the Enum should get it's values from Color table. "
So whats wrong with what you have? Anyway since you asked...
An enum is by definition inside the assembly. So as soon as a new color is added to the table you have an outdated Enum. But if you are ok with having upto date at build time. There is a good option.
Clearly the suggestion to use T4 is interesting . But the t4 would need to connect to DB and read it. When T4 goes beyond source generation, it can be easier to use a simple app. Unless of course you are already good at t4. So if t4 is a little hard for this task try:
A simple side app, that reads the DB and updates the EnumColor.cs would be plausible.
IE a simple console app. Place as a pre build step. The pre-build reads the DB, rewrites the enum.cs file and the compile/build then follows.
**Easy Alternative: using a Dictionary which you can extend at runtime **
Dictionary<int,string> colors
For me the first question is why? I had a similar technical need but the business need was to help with reporting. Enums works great to make code simpler to read and maintain, but is you have to create a report in say SSRS then you don't have access to the enums (okay I am sure some advanced SSRS users will say you can link in assemblies etc, but that is not the point). We played a bit with a prebuild script (could also run post build) to generate inline scaler function scripts to execute against the db. This way you could do select statements such as:
SELECT Model, fColorNameEnum(Color) FROM Car
This way you do not have to touch you reports again if you add a new element in your enum. I tend to use enums in the implementation of business logic, typically item status or workflow state. Adding a new option thus require adding new logic which means doing it in code. If you are never going to reason over the color value in code, then what is the reason for wanting to put it in an enum rather than just another linked object?
I am creating a tile-based game in XNA and will be loading the level information from xml files. I have no problem with loading xml data but I would like feedback on the approach I'm thinking of using for reading the xml file.
The code has a class hierarchy such that:
A Level class contains:
- a collection of TileLayers
- a collection of Tilesets
A TileLayer class contains
- a collection of Tiles
A Tileset class contains:
- a collection of TilsetTiles
A TilesetTile class contains:
- a TileId
- a collection of TileProperties
- a TileRectangle
Each of the above classes requires some information from the xml level file.
When I load a level I would like to simply call Level.Load();
My intention is that each class will have a Load() method that will:
1. Load any specific info it needs from the xml file.
2. Call Load() on its children.
The problem I see is that the code for processing the xml will be scattered around in different files making changes difficult to implement (for instance if I decide to encrypt the xml file), and no doubt breaks several aspects of the SOLID principles.
I have this idea that I could create an xmlLevelReader class whose sole purpose is to read an xml level file.
This class could then expose methods that can be called from the Load() method in each of the classes described above.
For example the TileLayer class Load() method could call xmlLevelReader.GetTiles() which would return an IEnumerable<Tile>
Do you think this approach will work?
Can you foresee any difficulties?
Is this approach too simplistic/complicated?
Any constructive criticism welcomed!
Thanks
Based on your comment, I see that you are using Tiled Map Editor. This lead me to suggest that you use TiledLib. Here is a brief explanation of how you can get up and running with importing your .tmx files for use in game.
Content Pipeline Overview
File -> Content Import -> Content Process -> Content Write -> .xnb -> ContentRead -> Game Object
TiledLib
TiledLib only handles the ContentImporter part of the above diagram. It will essentially handle reading the .tmx XML and allow you to process the data into whatever objects you need at run time. Fortunately, the TiledLib author has provided a Demos section in the download as well.
Basic Tiled Map Processor Demo
BasicDemo main game project which contains the ContentManager.Load call.
BasicDemoContent project which has the .tmx file from Tiled
BasicDemoContentPipeline project which has the ContentProcessor
TiledLib which has the ContentImporter
You really only need to worry about how the ContentProcessor works because TiledLib handles all the importing for you. Although I do suggest looking through the different classes to understand how it is deserializing the XML (for educational purposes).
The example ContentProcessor in the Basic Demo project takes in a MapContent object from the ContentImporter (TiledLib) and outputs a DemoMapContent object which is serialized to .xnb at build time and deserialized to a Map object at run time. Here are the classes that represent the map after being processed completely:
[ContentSerializerRuntimeType("BasicDemo.Map, BasicDemo")]
public class DemoMapContent
{
public int TileWidth;
public int TileHeight;
public List<DemoMapLayerContent> Layers = new List<DemoMapLayerContent>();
}
[ContentSerializerRuntimeType("BasicDemo.Layer, BasicDemo")]
public class DemoMapLayerContent
{
public int Width;
public int Height;
public DemoMapTileContent[] Tiles;
}
[ContentSerializerRuntimeType("BasicDemo.Tile, BasicDemo")]
public class DemoMapTileContent
{
public ExternalReference<Texture2DContent> Texture;
public Rectangle SourceRectangle;
public SpriteEffects SpriteEffects;
}
A Map contains a tile width, tile height, and a list of MapLayers.
A MapLayer contains a width, a height, and a list of Tiles.
A MapTile contains a texture, a source rectangle (proper rectangle in the tileset), and optional sprite effects (I've never used any).
How It's Made
I suggest reading the comments of the ContentProcessor to understand what is happening, but in brief, this is the basics:
Load texture data for tile set
Get source rectangles for each tile from within the texture
Iterate over all layers of the map
For each layer, iterate over all tiles
For each tile, get the proper texture and source rectangle
Assign all data from the input to the output properly
Caveats
As long as you stick to basic types (vague, I know), you also do not need to worry about ContentWriter and ContentReader parts of the content pipeline. It will automatically serialize and deserialize the .xnb files at build and run time, respectively. See a question I asked about this: here.
Also, you'll notice that if you're using object layers from within Tiled, the demo does not show you how to process those. TiledLib does properly import them, you just need to pull the data out and stick it in your proper classes. I'll try to edit this answer later with an example of how to do that.
If you are just wanting to load in XML without manipulating the data at all, you can just use the built in XNA Content Serializer.
Essentially you define a class which maps to your xml format, and then read the XML into an instance of that class.
For example. Here I define the class I want to load into:
SpriteRenderDefinition.cs
I chose this one because it has nested classes like the case you describe. Note that it goes into the ContentDefinitions project of you XNA solution.
Now here is the xml file that fills in the content of a SpriteRenderDefinition:
Sprite.xml
The format of that XML maps directly to the member names of SpriteRenderDefinition.
And finally, the code to actually load that XML data into an actual Object at runtime is very straight forward:
SpriteRenderDefinition def = GameObjectManager.pInstance.pContentManager.Load<SpriteRenderDefinition>(fileName);
After calling that line, you have a SpriteRenderDefintion object populated with all the content of the XML file! That is all the code I wrote. Everything else is built into XNA. It's really quite slick and useful if you take an hour or so to figure it out!
I am building a search application that has indexed several different data sources. When a query is performed against the search engine index, each search result specifies which data source it came from. I have built a factory pattern that I used to display a different template for each type of search result, but I've realized that this pattern will become more difficult to manage as more and more data sources are indexed by the search engine (i.e new code template has to be created for each new data source).
I created the following structure for my factory based off of an article by Granville Barnett over at DotNetSlackers.com
factory pattern http://img11.imageshack.us/img11/8382/factoryi.jpg
In order to make this search application easier to maintain, my thought was to create a set of database tables that can be used to define individual template types that my factory pattern could reference in order to determine which template to construct. I figured that I'd need to have a look up table that would be used to specify the type of template to build based off of the search result data source. I'd then need to have a table(s) to specify which fields to display for that template type. I'd also need a table (or additional columns within the template table) that would be use to define how to render that field (i.e. Hyperlink, Label, CssClass, etc).
Does anyone have any examples of a pattern like this? Please let me know.
Thanks,
-Robert
I would offer that this proposed solution is no less maintainable than simply associating a data source to the code template, as you currently have now. In fact, I would even go so far as to say you're going to lose flexibility by pushing the template schema and rendering information to a database, which will make your application harder to maintain.
For example, let's suppose you have these data sources with attributes (if I'm understanding this correctly):
Document { Author, DateModified }
Picture { Size, Caption, Image }
Song { Artist, Length, AlbumCover }
You then may have one of each of these data sources in your search results. Each element is rendered differently (Picture may be rendered with a preview image anchored to the left, or Song could display the album cover, etc.)
Let's just look at the rendering under your proposed design. You're going to query the database for the renderings and then adjust some HTML you are emitting, say because you want a green background for Documents and a blue one for Pictures. For the sake of argument, let's say you realize that you really need three background colors for Songs, two for Pictures, and one for Documents. Now, you're looking at a database schema change, which is promoted and pushed out, in addition to changing the parameterized template you're applying the rendering values to.
Let's say further you decide that the Document result needs a drop-down control, the Picture needs a few buttons, and Songs need a sound player control. Now, each template per data source changes drastically, so you're right back where you started, except now you have a database layer thrown in.
This is how the design breaks, because you've now lost the flexibility to define different templates per data source. The other thing you lose is having your templates versioned in source control.
I would look at how you can re-use common elements/controls in your emitted views, but keep the mapping in the factory between the template and the data source, and keep the templates as separate files per data source. Look at maintaining the rendering via CSS or similar configuration settings. For making it easier to maintain, considering exporting the mappings out as a simple XML file. To deploy a new data source, you simply add a mapping, create the appropriate template and CSS file, and drop them in to expected locations.
Response to comments below:
I meant a simple switch statement should suffice:
switch (resultType)
{
case (ResultType.Song):
factory = new SongResultFactory();
template = factory.BuildResult();
break;
// ...
Where you have the logic to output a given template. If you want something more compact than a long switch statement, you can create the mappings in a dictionary, like this:
IDictionary<ResultType, ResultFactory> TemplateMap;
mapping = new Dictionary<ResultType, ResultFactory>();
mapping.Add(ResultType.Song, new SongResultFactory());
// ... for all mappings.
Then, instead of a switch statement, you can do this one-liner:
template = TemplateMap[resultType].CreateTemplate();
My main argument was that at some point you still have to maintain the mappings - either in the database, a big switch statement, or this IDictionary instance that needs to be initialized.
You can take it further and store the mappings in a simple XML file that's read in:
<TemplateMap>
<Mapping ResultType="Song" ResultFactoryType="SongResultFactory" />
<!-- ... -->
</TemplateMap>
And use reflection et. al. to populate the IDictionary. You're still maintaining the mappings, but now in an XML file, which might be easier to deploy.
I am working on a custom ArcGIS Desktop tool project and I would like to implement an automated linear referencing feature in it. To make a long story short, I would like to display problematic segments along a route and show the severity by using a color code (say green, yellow, red, etc.). I know this is a pretty common scenario and have come to understand that the "right way" of accomplishing this task is to create a linear event table which will allow me to assign different codes to certain route segments. Some of my colleagues know how to do it manually but I can't seem to find any way to replicate this programaticaly.
The current tool is written in C# and already performs all the needed calculations to determine the problematic areas. The problem mainly is that I don't know where to start since I don't know a lot about ArcObjects. Any code sample or suggestion is welcome (C# is preferred but C++, VB and others will surely help me anyway).
EDIT :
I'm trying to use the MakeRouteEventLayer tool but can't seem to get the different pre-conditions met. The routes are hosted on an SDE server. So far, I am establishing a connection this way :
ESRI.ArcGIS.esriSystem.IPropertySet pConnectionProperties = new ESRI.ArcGIS.esriSystem.PropertySet();
ESRI.ArcGIS.Geodatabase.IWorkspaceFactory pWorkspaceFactory;
ESRI.ArcGIS.Geodatabase.IWorkspace pWorkspace;
ESRI.ArcGIS.Location.ILocatorManager pLocatorManager;
ESRI.ArcGIS.Location.IDatabaseLocatorWorkspace pDatabaseLocatorWorkspace;
pConnectionProperties.SetProperty("server", "xxxx");
pConnectionProperties.SetProperty("instance", "yyyy");
pConnectionProperties.SetProperty("database", "zzzz");
pConnectionProperties.SetProperty("AUTHENTICATION_MODE", "OSA");
pConnectionProperties.SetProperty("version", "dbo.DEFAULT");
pWorkspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactory();
pWorkspace = pWorkspaceFactory.Open(pConnectionProperties, 0);
pLocatorManager = new ESRI.ArcGIS.Location.LocatorManager();
pDatabaseLocatorWorkspace = (ESRI.ArcGIS.Location.IDatabaseLocatorWorkspace)pLocatorManager.GetLocatorWorkspace(pWorkspace);
Now I am stuck trying to prepare everything for MakeRouteEventLayer's constructor. I can't seem to find how i'm supposed to get the Feature Layer to pass as the Input Route Features. Also, I don't understand how to create an event table properly. I can't seem to find any exemple relating to what I am trying to accomplish aside from this one which I don't understand since it isn't documented/commented and the datatypes are not mentionned.
I'm not entirely certain what it is you want to do. If you want to get Linear Referencing values or manipulate them directly in a feature class that already has linear referencing defined, that's pretty straight forward.
IFeatureClass fc = ....;
IFeature feature = fc.GetFeature(...);
IMSegmentation3 seg = (IMSegmentation3)feature;
... blah ...
If you need to create a Feature class with linear referencing, you should start witht he "Geoprocessing" tools in the ArcToolbox. If the out-of-the-box tools can do most of what you need, this will minimize your coding.
I would strongly recommend trying to figure what you need to do with ArcMap if at all possible... then backing out the ArcObjects.
Linear Referencing API
Linear Referencing Toolbox
Understanding Linear Referencing