I'm trying to create new vector layer with the same fields as contained in original layer.
original_layer_fields_list = original_layer.fields().toList()
new_layer = QgsVectorLayer("Point", "new_layer", "memory")
pr = new_layer.dataProvider()
However, when I try:
for fld in original_layer_fields_list:
type_name = fld.typeName()
pr.addAttributes([QgsField(name = fld.name(), typeName = type_name)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
I get a layer with no fields in attribute table.
If I try something like:
for fld in original_layer_fields_list:
if fld.type() == 2:
pr.addAttributes([QgsField(name = fld.name(), type = QVariant.Int)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
... it works like charm.
Anyway ... I'd rather like the first solution to work in case if one wants to automate the process and not check for every field type and then find an appropriate code. Besides - I really am not able to find any documentation about codes for data types. I managed to find this post https://gis.stackexchange.com/questions/353975/get-only-fields-with-datatype-int-in-pyqgis where in comments Kadir pointed on this sourcecode (https://codebrowser.dev/qt5/qtbase/src/corelib/kernel/qvariant.h.html#QVariant::Type).
I'd really be thankful for any kind of direction.
For nim language there is only one gui toolkit working for me and that is gintro.
The democode listview compiles and runs nice on my netbsd.
Source:
http://ssalewski.de/gintroreadme.html
But I need a listview(gtktreeview) with two columns, I looked into nim.gtk but can't figure out which "casts" I should spell.
The code in the demo program:
let gtype = typeFromName("gchararray")
let store = newListStore(N_COLUMNS, cast[pointer]( unsafeaddr gtype))
# cast due to bug in gtk.nim
Works nice for N_COLUMNS=1 but not N_COLUMNS:2
Here is the relevant part in nim.gtk:
proc newListStore*(nColumns: int; types: GTypeArray): ListStore =
let gobj = gtk_list_store_newv(int32(nColumns), types)
Second when I have multiple colums I would like to make it sortable by clicking on the header (like an excel table)
I think you need something like this:
let gtypes = [typeFromName("gchararray"), typeFromName("gchararray")] # Be sure to change the types to whatever you need.
let store = newListStore(N_COLUMNS, addr gtype[0]) # You shouldn't need this weird cast here.
Untested but should work. Feel free to join our Gitter/IRC if you need more help :)
i am trying to make a game where players create their own buildings and can then save them for other players to see and play on. However, roblox doesn't let me store all the data needed for the whole creation(there are several properties for each brick)
All i get is this error code:
104: Cannot store Array in DataStore
any help would be greatly appreciated!
I'm not sure if this is the best method, but it's my attempt. Below is an example of a table, you can use tables to store several values. I think you can use HttpService's JSONEncode function to convert tables into strings (which hopefully can be saved more efficiently)
JSONEncode (putting brick's data into a string, which you can save into the DataStore
local HttpService = game:GetService("HttpService")
-- this is an example of what we'll convert into a json string
local exampleBrick = {
["Size"] = Vector3.new(3,3,3),
["Position"] = Vector3.new(0,1.5,0),
["BrickColor"] = BrickColor.new("White")
["Material"] = "Concrete"
}
local brickJSON = HttpService:JSONEncode(exampleBrick)
print(brickJSON)
-- when printed, you'll get something like
-- { "Size": Vector3.new(3,3,3), "Position": Vector3.new(0,1.5,0), "BrickColor": BrickColor.new("White"), "Material": "Concrete"}
-- if you want to refer to this string in a script, surround it with two square brackets ([[) e.g. [[{"Size": Vector3.new(3,3,3)... }]]
JSONDecode (reading the string and converting it back into a brick)
local HttpService = game:GetService("HttpService")
local brickJSON = [[ {"Size": Vector3.new(3,3,3), "Position": Vector3.new(0,1.5,0), "BrickColor": BrickColor.new("White"), "Material": "Concrete"} ]]
function createBrick(tab)
local brick = Instance.new("Part")
brick.Parent = <insert parent here>
brick.Size = tab[1]
brick.Position= tab[2]
brick.BrickColor= tab[3]
brick.Material= tab[4]
end
local brickData = HttpService:JSONDecode(brickJSON)
createBrick(brickData) --this line actually spawns the brick
The function can also be wrapped in a pcall if you want to account for any possible datastore errors.
Encoding a whole model into a string
Say your player's 'building' is a model, you can use the above encode script to convert all parts inside a model into a json string to save.
local HttpService = game:GetService("HttpService")
local StuffWeWantToSave = {}
function getPartData(part)
return( {part.Size,part.Position,part.BrickColor,part.Material} )
end
local model = workspace.Building --change this to what the model is
local modelTable = model:Descendants()
for i,v in pairs(modelTable) do
if v:IsA("Part") or v:IsA("WedgePart") then
table.insert(StuffWeWantToSave, HttpService:JSONEncode(getPartData(modelTable[v])))
end
end
Decoding a string into a whole model
This will probably occur when the server is loading a player's data.
local HttpService = game:GetService("HttpService")
local SavedStuff = game:GetService("DataStoreService"):GetDataStore("blabla") --I don't know how you save your data, so you'll need to adjust this and the rest of the scripts (as long as you've saved the string somewhere in the player's DataStore)
function createBrick(tab)
local brick = Instance.new("Part")
brick.Parent = <insert parent here>
brick.Size = tab[1]
brick.Position= tab[2]
brick.BrickColor= tab[3]
brick.Material= tab[4]
end
local model = Instance.new("Model") --if you already have 'bases' for the players to load their stuff in, remove this instance.new
model.Parent = workspace
for i,v in pairs(SavedStuff) do
if v[1] ~= nil then
CreateBrick(v)
end
end
FilteringEnabled
If your game uses filteringenabled, make sure that only the server handles saving and loading data!! (you probably already knew that) If you want the player to save by clicking a gui button, make the gui button fire a RemoteFunction that sends their base's data to the server to convert it to a string.
BTW I'm not that good at scripting so I've probably made a mistake somehwere.. good luck though
Crabway's answer is correct in that the HttpService's JSONEncode and JSONDecode methods are the way to go about tackling this problem. As it says on the developer reference page for the DataStoreService, Data is ... saved as a string in data stores, regardless of its initial type. (https://developer.roblox.com/articles/Datastore-Errors.) This explains the error you received, as you cannot simply push a table to the data store; instead, you must first encode a table's data into a string using JSONEncode.
While I agree with much of Crabway's answer, I believe the function createBrick would not behave as intended. Consider the following trivial example:
httpService = game:GetService("HttpService")
t = {
hello = 1,
goodbye = 2
}
s = httpService:JSONEncode(t)
print(s)
> {"goodbye":2,"hello":1}
u = httpService:JSONDecode(s)
for k, v in pairs(u) do print(k, v) end
> hello 1
> goodbye 2
As you can see, the table returned by JSONDecode, like the original, uses strings as keys rather than numeric indices. Therefore, createBrick should be written something like this:
function createBrick(t)
local brick = Instance.new("Part")
brick.Size = t.Size
brick.Position = t.Position
brick.BrickColor = t.BrickColor
brick.Material = t.Material
-- FIXME: set any other necessary properties.
-- NOTE: try to set parent last for optimization reasons.
brick.Parent = t.Parent
return brick
end
As for encoding a model, calling GetChildren would produce a table of the model's children, which you could then loop through and encode the properties of everything within. Note that in Crabway's answer, he only accounts for Parts and WedgeParts. You should account for all parts using object:IsA("BasePart") and also check for unions with object:IsA("UnionOperation"). The following is a very basic example in which I do not store the encoded data; rather, I am just trying to show how to check the necessary cases.
function encodeModel(model)
local children = model:GetChildren()
for _, child in ipairs(children) do
if ((child:IsA("BasePart")) or (child:IsA("UnionOperation"))) then
-- FIXME: encode child
else if (child:IsA("Model")) then
-- FIXME: using recursion, loop through the sub-model's children.
end
end
return
end
For userdata, such as Vector3s or BrickColors, you will probably want to convert those to strings when you go to encode them with JSONEncode.
-- Example: part with "Brick red" BrickColor.
color = tostring(part.BrickColor)
print(string.format("%q", color))
> "Bright red"
I suggest what #Crabway said, use HttpService.
local httpService = game:GetService("HttpService")
print(httpService:JSONEncode({a = "b", b = "c"}) -- {"a":"b","b":"c"}
But if you have any UserData values such as Vector3s, CFrames, Color3s, BrickColors and Enum items, then use this library by Defaultio. It's actually pretty nice.
local library = require(workspace:WaitForChild("JSONWithUserdata"))
library:Encode({Vector3.new(0, 0, 0)})
If you want a little documentation, then look at the first comment in the script:
-- Defaultio
--[[
This module adds support for encoding userdata values to JSON strings.
It also supports lists which skip indices, such as {[1] = "a", [2] = "b", [4] = "c"}
Userdata support is implemented by replacing userdata types with a new table, with keys _T and _V:
_T = userdata type enum (index in the supportedUserdataTypes list)
_V = a value or table representing the value
Follow the examples bellow to add suppport for additional userdata types.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Usage example:
local myTable = {CFrame.new(), BrickColor.Random(), 4, "String", Enum.Material.CorrodedMetal}
local jsonModule = require(PATH_TO_MODULE)
local jsonString = jsonModule:Encode(myTable)
local decodedTable = jsonModule:Decode(jsonString)
--]]
I am developing an application using Dashdb on Bluemix and nodered, my PHP application uses the call to webservice to invoke the node-red, whenever my function on PHP invokes the node to insert on table and the field GEO_ID is null, the application fails, I understand the issue, it seems the third parameter was not informed, I have just tried to check the param before and passing something like NULL but it continues not working.
See the code:
msg.account_id = msg.req.query.account_id;
msg.user_id = msg.req.query.user_id;
msg.geo_id=msg.req.query.geo_id;
msg.payload = "INSERT INTO ACCOUNT_USER (ACCOUNT_ID, USER_ID, GEO_ID) VALUES (?,?,?) ";
return msg;
And on Dashdb component I have set the parameter as below:
msg.account_id,msg.user_id,msg.geo_id
The third geo_id is the issue, I have tried something like the code below:
if(msg.req.query.geo_id===null){msg.geo_id=null}
or
if(msg.req.query.geo_id===null){msg.geo_id="null"}
The error I got is the one below:
dashDB query node: Error: [IBM][CLI Driver][DB2/LINUXX8664] SQL0420N Invalid character found in a character string argument of the function "DECIMAL". SQLSTATE=22018
I really appreciate if someone could help me on it .
Thanks,
Eduardo Diogo Garcia
Is it possible that msg.req.query.geo_id is set to an empty string?
In that case neither if statement above would get executed, and you would be trying to insert an empty string into a DECIMAL column. Maybe try something like this:
if (! msg.req.query.geo_id || msg.req.query.geo_id == '') {
msg.geo_id = null;
}
I have a requirement to convert the output of cypher into JSON.
Here is my code snippet.
RestCypherQueryEngine rcqer=new RestCypherQueryEngine(restapi);
String nodeN = "MATCH n=(Company) WITH COLLECT(n) AS paths RETURN EXTRACT(k IN paths | LAST(nodes(k))) as lastNode";
final QueryResult<Map<String,Object>> queryResult = rcqer.query(searchQuery);
for(Map<String,Object> row:queryResult)
{
System.out.println((ArrayList)row.get("lastNode"));
}
Output:
[http://XXX.YY6.192.103:7474/db/data/node/445, http://XXX.YY6.192.103:7474/db/data/node/446, http://XXX.YY6.192.103:7474/db/data/node/447, http://XXX.YY6.192.103:7474/db/data/node/448, http://XXX.YY6.192.103:7474/db/data/node/449, http://XXX.YY6.192.103:7474/db/data/node/450, http://XXX.YY6.192.103:7474/db/data/node/451, http://XXX.YY6.192.103:7474/db/data/node/452, http://XXX.YY6.192.103:7474/db/data/node/453]
I am not able to see the actual data (I am getting URL's). I am pretty sure I am missing something here.
I would also like to convert the output to JSON.
The cypher works in my browser interface.
I looked at various articles around this:
Java neo4j, REST and memory
Neo4j Cypher: How to iterate over ExecutionResult result
Converting ExecutionResult object to json
The last 2 make use of EmbeddedDatabase which may not be possible in my scenario (as the Neo is hosted in another cloud, hence the usage of REST).
Thanks.
Try to understand what you're doing? Your query does not make sense at all.
Perhaps you should re-visit the online course for Cypher: http://neo4j.com/online-course
MATCH n=(Company) WITH COLLECT(n) AS paths RETURN EXTRACT(k IN paths | LAST(nodes(k))) as lastNode
you can just do:
MATCH (c:Company) RETURN c
RestCypherQueryEngine rcqer=new RestCypherQueryEngine(restapi);
final QueryResult<Map<String,Object>> queryResult = rcqer.query(query);
for(Node node : queryResult.to(Node.class))
{
for (String prop : node.getPropertyKeys()) {
System.out.println(prop+" "+node.getProperty(prop));
}
}
I think it's better to use the JDBC driver for what you try to do, and also actually return the properties you're trying to convert to JSON.